Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Сила Pattern Matching

Сила Pattern Matching

Владимир Филонов: Pattern Matching - один из основных методов работы со структурированными данными в Erlang\Elixir. Поговорим о том, чем он удобен, зачем нужен и как им пользоваться с практическими примерами: http://elixir-lang.moscow/events/1/talks/sila-pattern-matching

Sobolev Nikita

September 23, 2016
Tweet

More Decks by Sobolev Nikita

Other Decks in Programming

Transcript

  1. 5

  2. 7 iex(1)> x = 1 1 iex(2)> 1 = x

    1 Присвоение и сравнение
  3. 8 iex(1)> x = 1 1 iex(2)> 1 = x

    1 iex(3)> 2 = x ** (MatchError) no match of right hand side value: 1 Присвоение и сравнение
  4. 9 1> X = 1. 1 2> X = 2.

    ** exception error: no match of right hand side value 2 Erlang
  5. 10 iex(1)> x = 1 1 iex(2)> x = 2

    2 iex(2)> ^x = 3 ** (MatchError) no match of right hand side value: 2 Elixir
  6. 11 Кортежи iex(1)> t = {:ok, "some result"} iex(2)> {:ok,

    result} = t {:ok, "result"} iex(3)> result "result"
  7. 12 Списки iex(1)> list = [1, 2, 3] iex(2)> [head|tail]

    = list iex(3)> head 1 iex(3)> tail [2, 3]
  8. 17 Зачем это? case File.read("/root/secret") do {:ok, data} -> IO.puts

    data {:error, :enoent} -> IO.puts "No file" {:error, error} -> IO.puts ["Unexpected: " | to_string(error)] end
  9. 22 Перегрузка функций iex(1)> IO.puts WhatsThis.this_is() This is nothing iex(2)>

    IO.puts WhatsThis.this_is("something") This is something iex(3)> IO.puts WhatsThis.this_is("something", "else") ** (UndefinedFunctionError) function WhatsThis.this_is/2 is undefined or private.
  10. 24 defmodule Math do def sum(args) do sum(args, 0) end

    def sum([], result) do result end def sum([arg|args], result) do sum(args, result+arg) end end
  11. def sum(arg1, arg2) do ... def sum([], result) do ...

    def sum([arg|args], result) do ... 28 Порядок шаблонов
  12. warning: this clause cannot match because a previous clause at

    line 6 always matches math.ex:10 29 Порядок шаблонов
  13. 30 iex(1)> Math.sum(1, 2) 3 iex(2)> Math.sum([1, 2, 3]) **

    (ArithmeticError) bad argument in arithmetic expression math.ex:7: Math.sum/2
  14. def sum([], result) do ... def sum([arg|args], result) do …

    def sum(arg1, arg2) do ... 31 Порядок шаблонов
  15. def func(arg) when expr do ... case arg do A

    when expr -> ... A when expr2 -> ... 35 Guards
  16. def sum(arg1, arg2) when is_integer(arg1) and is_integer(arg2) do arg1+arg2 end

    def sum(arg1, arg2) when is_integer(arg1) and is_list(arg2) do sum(arg2, arg1) end 36 Guards
  17. 39 iex(1)> data = <<1, 2, 3, 4, 5, 6,

    7, 8>> <<1, 2, 3, 4, 5, 6, 7, 8>>
  18. 40 iex(1)> data = <<1, 2, 3, 4, 5, 6,

    7, 8, >> <<1, 2, 3, 4, 5, 6, 7, 8>> iex(2)> <<header :: 32, body :: bits>> = data iex(3)> header <<1, 2, 3, 4>>
  19. 41 iex(1)> data = <<1, 2, 3, 4, 5, 6,

    7, 8, >> <<1, 2, 3, 4, 5, 6, 7, 8>> iex(2)> <<header :: 32, body :: bits>> = data iex(3)> header <<1, 2, 3, 4>> iex(4)> <<header :: binary-size(4), body :: binary>> = data
  20. 42 iex(1)> data = <<1, 2, 3, 4, 5, 6,

    7, 8, >> <<1, 2, 3, 4, 5, 6, 7, 8>> iex(2)> <<header :: 32, body :: bits>> = data iex(3)> header <<1, 2, 3, 4>> iex(4)> <<header :: binary-size(4), body :: binary>> = data
  21. 45 case File.read(file_name) do {:ok, mp3} -> parse_mp3(mp3) {:error, error}

    -> IO.puts "Couldn't open #{file_name}. #{error}" end
  22. 48 <<84, 65, 71, 89, 101, 115, 116, 101, 114,

    100, 97, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 101, 97, 116, 108, 101, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...>>
  23. 49 << "TAG", title :: binary-size(30), artist :: binary-size(30), album

    :: binary-size(30), year :: binary-size(4), comment :: binary-size(30), _rest :: binary >> = id3_tag
  24. 50 iex(1)> IO.puts 'title: #{title}' title: Yesterday iex(2)> IO.puts 'artist:

    #{artist}' artist: Beatles iex(3)> IO.puts 'album: #{album}' album: The Beatles
  25. 53 << sync :: 11, version :: 2, layer ::

    2, protection :: 1, bitrate :: 4, frequency :: 2, padding :: 1, _priv :: 1, mode :: 2, mode_ext :: 2, copyright :: 1, is_copy :: 1, emphasis :: 2 >> = mp3_frame_header