Share
Embed
Transcript
48 slides
-
จ๏σʔλܕ iex> 1 # integer iex> 0x1F # integer iex>
1.0 # float iex> true # boolean iex> :atom # atom / symbol iex> "elixir" # string (binary) iex> <<1, 2>> # binary iex> [1, 2, 3] # list iex> {1, 2, 3} # tuple iex> %{a: 1} # map -
จ๏Ϟδϡʔϧ iex> defmodule Math do ...> def sum(a, b) do
...> a + b ...> end ...> end iex> Math.sum(1, 2) 3 -
จ๏ύλʔϯϚον iex> x = 1 1 iex> x = 2
2 iex> x = 1 1 iex> ^x = 2 ** (MatchError) no match of right hand side value: 2 ɾσϑΥϧτͰมͷ࠶ଋറՄೳ ɾ?Λ಄ʹ͚ͭΔͱ࠶ଋറ͠ͳ͍ -
จ๏ύλʔϯϚον iex> [head | tail] = [1, 2, 3] [1,
2, 3] iex> head 1 iex> tail [2, 3] iex> {a, b, c} = {:hello, "world", 42} {:hello, "world", 42} iex> a :hello iex> b "world" -
จ๏ύλʔϯϚον iex> defmodule Fib do ...> def fib(0), do: 1
...> def fib(1), do: 1 ...> def fib(n), do: fib(n-1) + fib(n-2) ...> end Fib.fib(5) ɾؔͷҾͰύλʔϯϚον ɾ࠶ؼΛ͏ -
จ๏੍ޚߏจDBTF iex> case {1, 2, 3} do ...> {4, 5,
6} -> ...> "This clause won't match" ...> {1, x, 3} -> ...> "This clause will match and bind x to 2 in this clause" ...> _ -> ...> "This clause would match any value" ...> end ɾϚονͨ͠અ͕࣮ߦ͞ΕΔ ɾϚονͰଋറ͞ΕͨมͦͷઅͰͷΈ༻Մೳ -
จ๏੍ޚߏจDPOE iex> cond do ...> 2 + 2 == 5
-> ...> "This will not be true" ...> 2 * 2 == 3 -> ...> "Nor this" ...> 1 + 1 == 2 -> ...> "But this will" ...> end “But this will” ɾ࠷ॳʹUSVFʹͳͬͨઅ͕࣮ߦ͞ΕΔ -
จ๏੍ޚߏจJGVOMFTT iex> if nil do ...> "This won't be seen"
...> else ...> "This will" ...> end -
จ๏จࣈྻͱਖ਼نදݱ iex> String.split "͜Μʹͪ", "ʹ" ["͜Μ", "ͪ"] iex> "͜Μʹͪ" =~
~r/ʹ/ true ɾ65' ɾ࣮ମCJOBSZ -
จ๏4USVDU iex> defmodule User do ...> defstruct name: "john", age:
27 ...> end {:module, User, <<70, 79, 82, ...>>, {:__struct__, 0}} iex> john = %User{} %User{age: 27, name: "john"} iex> john.name "john" iex> %User{name: name} = john %User{age: 27, name: "john"} iex> name "john" ɾϢʔβఆٛͷσʔλܕ ɾߏମΈ͍ͨͳͷ -
จ๏1SPUPDPM iex> Blank.blank?(%{a: 1}) false iex> Blank.blank?([1, 2, 3]) false
iex> Blank.blank?(%{}) true iex> Blank.blank?([]) true defprotocol Blank do def blank?(data) end defimpl Blank, for: Map do def blank?(map) do map_size(map) == 0 end end defimpl Blank, for: List do def blank?([]), do: true def blank?(_), do: false end ɾϙϦϞʔϑΟζϜΛ࣮ݱ͢ΔͨΊͷͷ ɾEFGQSPUPDPMͰϓϩτίϧΛఆٛ ɾEFpNQMͰϓϩτίϧΛ࣮ -
จ๏4USVDUͱ1SPUPDPM iex> Blank.blank?(%User{}) ** (Protocol.UndefinedError) protocol Blank not implemented for
%User{age: 27, name: "john"} iex> Blank.blank?(%User{}) false defprotocol Blank do def blank?(data) end defimpl Blank, for: User do def blank?(_), do: false end ɾϢʔβఆٛͷ4USVDUʹରͯ͠1SPUPDPMΛ࣮Մೳ -
จ๏&OVNFSBCMFͱ4USFBN iex> Enum.map([1, 2, 3], fn x -> x *
2 end) [2, 4, 6] iex> Enum.map(%{1 => 2, 3 => 4}, fn {k, v} -> k * v end) [2, 12] iex> stream = Stream.cycle([1, 2, 3]) #Function<15.16982430/2 in Stream.cycle/1> iex> Enum.take(stream, 10) [1, 2, 3, 1, 2, 3, 1, 2, 3, 1] ɾ&OVNFSBCMFͳσʔλߏͷૢ࡞Λ͢ΔͨΊͷϓϩτίϧ ɾͪΖΜϢʔβఆٛͷ4USVDU࣮Մೳ ɾ4USFBNԆૢ࡞ͷͨΊͷϞδϡʔϧ -
จ๏ϚΫϩRVPUFVORVPUF iex> quote do ...> sum(1, 2) ...> end {:sum,
[], [1, 2]} iex> Macro.to_string(quote do: sum(1, 2)) "sum(1, 2)" iex> number = 3 3 iex> Macro.to_string(quote do: sum(1, unquote(number))) "sum(1, 3)" ɾRVPUFͰࣜͷ"45ʹม͢Δ ɾVORVPUFͰ"45ʹΛຒΊࠐΉ -
จ๏ϚΫϩ # unless.ex defmodule Unless do def fun_unless(clause, expression) do
if !clause do expression end end defmacro macro_unless(clause, expression) do quote do if !unquote(clause) do unquote(expression) end end end end -
จ๏ϚΫϩ $ iex unless.ex iex> require Unless nil iex> Unless.macro_unless
true do ...> IO.puts "දࣔ͞Ε·ͤΜ" ...> end nil iex> Unless.fun_unless true do ...> IO.puts "දࣔ͞Ε·ͤΜ" ...> end දࣔ͞Ε·ͤΜ nil -
จ๏ϓϩηε iex> pid = spawn fn -> 1 + 2
end #PID<0.44.0> iex> Process.alive?(pid) false iex> send self(), {:hello, "world"} {:hello, "world"} iex> receive do ...> {:hello, msg} -> msg ...> {:world, msg} -> "won't match" ...> end "world" -
.JYϓϩδΣΫτͷ࡞ NJYOFX $ mix new spam * creating README.md *
creating .gitignore * creating mix.exs * creating config * creating config/config.exs * creating lib * creating lib/spam.ex * creating test * creating test/test_helper.exs * creating test/spam_test.exs ... $ cd spam $ ls README.md _build config deps lib mix.exs mix.lock test -
.JY࣮ߦ JFY4NJY # lib/spam.ex defmodule Spam do def sum(a, b)
do a + b end end $ iex -S mix Erlang/OTP 17 [erts-6.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async- threads:10] [hipe] [kernel-poll:false] [dtrace] Interactive Elixir (1.1.0-dev) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> Spam.sum(1, 2) 3 -
.JYςετ NJYUFTU # test/spam_test.exs defmodule SpamTest do use ExUnit.Case test
"the truth" do assert Spam.sum(1, 2) == 3 end end $ mix test Compiled lib/spam.ex Generated spam.app . Finished in 0.03 seconds (0.03s on load, 0.00s on tests) 1 tests, 0 failures Randomized with seed 45042 ɾ&Y6OJUͱ͍͏ϢχοτςετϥΠϒϥϦ͕ඪ४ఴ -
.JYςετ NJYUFTU # test/spam_test.exs defmodule SpamTest do use ExUnit.Case test
"the truth" do assert Spam.sum(1, 2) == 2 end end $ mix test 1) test the truth (SpamTest) test/spam_test.exs:4 Assertion with == failed code: Spam.sum(1, 2) == 2 lhs: 3 rhs: 2 stacktrace: test/spam_test.exs:5 Finished in 0.03 seconds (0.03s on load, 0.00s on tests) 1 tests, 1 failures Randomized with seed 983758 -
.JYґଘղܾ NJYEFQTHFU # mix.exs defmodule Spam.Mixfile do use Mix.Project ...
defp deps do [{:message_pack, "~> 0.1.4"}] end end $ mix deps.get Dependency resolution completed successfully * Getting message_pack (Hex package) Checking package (https:// s3.amazonaws.com/s3.hex.pm/tarballs/ message_pack-0.1.4.tar) Using locally cached package Unpacked package tarball (/Users/ yuki_ito/.hex/packages/ message_pack-0.1.4.tar) $ iex -S mix iex(1)> MessagePack.pack([]) {:ok, <<144>>} ɾઃఆϑΝΠϧ NJYFYT Ͱઃఆ -
.JYґଘղܾ NJYEFQTHFU # mix.exs defmodule Spam.Mixfile do use Mix.Project ...
defp deps do [{:websocket_client, github: "jeremyong/websocket_client", only: :test}] end end ɾHJUIVCͳͲͷϦϙδτϦ 63*ͰͷࢦఆՄೳ ɾUFTU࣌ͷΈ༻͢ΔɺΈ͍ͨͳࢦఆՄೳ -
.JYSFMFBTF SEQBSUZ defmodule Spam.Mixfile do use Mix.Project ... defp deps
do [{:exrm, "~> 0.14.11"}] end end $ mix release ==> Building release with MIX_ENV=dev. ... ==> The release for spam-0.0.1 is ready! $ ./rel/spam/bin/spam console ... Erlang/OTP 17 [erts-6.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace] Interactive Elixir (1.1.0-dev) - press Ctrl +C to exit (type h() ENTER for help) iex([email protected])1> Spam.sum(1, 2) 3 ɾϦϦʔεFYSN IUUQTHJUIVCDPNCJUXBMLFSFYSN Ͱ࡞Մೳ ɾকདྷతʹσϑΥϧτͰαϙʔτ͞ΕΔํ -
.JYEJBMZ[FS SEQBSUZ defmodule Spam do @spec sum(integer(), integer()) :: list()
def sum(a, b) do a + b end end $ mix compile $ mix dialyzer Starting Dialyzer dialyzer --no_check_plt --plt ~/.dialyxir_core_17_1.0.2.plt - Wunmatched_returns -Werror_handling -Wrace_conditions -Wunderspecs ./ebin Proceeding with analysis... spam.ex:2: Invalid type specification for function 'Elixir.Spam':sum/2. The success typing is (number(),number()) -> number() done in 0m0.88s done (warnings were emitted) ɾEJBMZ[FSEJBMZYJS IUUQTHJUIVCDPNKFSFNZKIEJBMZYJS Ͱ࣮ߦՄೳ -
υΩϡϝϯτ @doc """ Returns a new collection, where each item
is the result of invoking `fun` on each corresponding item of `collection`. For dicts, the function expects a key-value tuple. ## Examples iex> Enum.map([1, 2, 3], fn(x) -> x * 2 end) [2, 4, 6] iex> Enum.map([a: 1, b: 2], fn({k, v}) -> {k, -v} end) [a: -1, b: -2] """ @spec map(t, (element -> any)) :: list def map... -
υΩϡϝϯτ iex(1)> h Enum.map def map(collection, fun) Returns a new
collection, where each item is the result of invoking fun on each corresponding item of collection. For dicts, the function expects a key-value tuple. Examples ᴺ iex> Enum.map([1, 2, 3], fn(x) -> x * 2 end) ᴺ [2, 4, 6] ᴺ ᴺ iex> Enum.map([a: 1, b: 2], fn({k, v}) -> {k, -v} end) ᴺ [a: -1, b: -2]