読者です 読者をやめる 読者になる 読者になる

日常

ケ・セラ・セラ

Elixir 触れてみた2

elixir

以下を参考に、もう少し触れてみた。基礎文法最速マスターありがたい。


iex で入力していてよくわからなくなった時は #iex:break する

IO.write "foo" # => 改行なし

IO.puts "foo" # => 改行あり

IO.inspect 123 # => デバッグ

Ruby でいうところの「p デバッグ」は,Elixir では「IO.inspect デバッグ

オブジェクト指向言語ではないのでインスタンス変数はありませんが, モジュールの中で @変数名 値 とすることでモジュール内で共通して値を利用できます.ただし値の変更はできません.

defmodule Foo do @val "hoge" def x do @val end end Foo.x # => "hoge"

iiex(9)> n = 1000
1000
iex(10)> n
1000
iex(11)> n = 1_000
1000
iex(12)> n
1000
iex(13)> ^n = 1000
1000
iex(14)> ^n = 1____000
** (SyntaxError) iex:14: syntax error before: '____000'

iex(14)> ^n = 1_000
1000

剰余

iex(15)> n = rem(5, 2)
1

インクリメントとデクリメント は Elixir にはない。 += -= というのもない。 x = x + 1 とする。

'' "" どちらのクォートの中でも \t( タブ ) や \n( 改行 ) などの特殊文字を利用可

iex(17)> IO.inspect("a\tbc\n")
"a\tbc\n"
"a\tbc\n"
iex(18)> str1 = "aaa" <> "bbb"
"aaabbb"
iex(19)> str2 = Enum.join(["aaa", "bbb", "ccc"], ",")
"aaa,bbb,ccc"
iex(20)> str2 = Enum.join(["aaa", "bbb", "ccc"], "_")
"aaa_bbb_ccc"
iex(21)> str3 = String.split("aaa,bbb,ccc", ~r/,/)
["aaa", "bbb", "ccc"]
iex(22)> String.split("abcde", ~r//)
["a", "b", "c", "d", "e", ""]
iex(23)> String.length("abcde")
5
iex(24)> substr = String.slice("abcd", 0, 2)
"ab"
iex(25)> substr = String.slice("abcd", 0..1)
"ab"
iex(26)> substr = String.slice("abcd", 1..2)
"bc"
iex(27)> [{idx, _}] = Regex.run(~r/bc/, "abcd", return: :index)
[{1, 2}]
iex(28)> a = [100, 200, 300]
[100, 200, 300]
iex(29)> Enum.at(a, 0)
100
iex(30)> Enum.at(a, 1)
200
iex(31)> Enum.at(a, 2)
300
iex(32)> Enum.at(a, 3)
nil
iex(33)> List.insert_at(a, 0, 1)
[1, 100, 200, 300]
iex(34)> List.insert_at(a, 0, 2)
[2, 100, 200, 300]
iex(35)> List.insert_at(a, 1, 555)
[100, 555, 200, 300]
iex(36)> a
[100, 200, 300]
iex(37)> List.insert_at(a, 2, 555)
[100, 200, 555, 300]
iex(38)> List.insert_at(a, 3, 555)
[100, 200, 300, 555]
iex(39)> List.insert_at(a, 4, 555)
[100, 200, 300, 555]
iex(40)> a
[100, 200, 300]
iex(41)> length(a)
3
iex(42)> Enum.count(a)
3
iex(43)> list.last(a)
** (RuntimeError) undefined function: list/0

iex(43)> a
[100, 200, 300]
iex(44)> List.last(a)
300
iex(45)> List.insert_at(a, -1, 999)
[100, 200, 300, 999]
iex(64)> map = %{a: 1, b: 2}
%{a: 1, b: 2}
iex(65)> map
%{a: 1, b: 2}
iex(66)> map.put(map, :c, 5)
** (ArgumentError) argument error
    :erlang.apply(%{a: 1, b: 2}, :put, [%{a: 1, b: 2}, :c, 5])
iex(66)> Map.put(map, :c, 5)
%{a: 1, b: 2, c: 5}
iex(67)> Map.put(map, d: 9)
** (UndefinedFunctionError) undefined function: Map.put/2
    (elixir) Map.put(%{a: 1, b: 2}, [d: 9])
iex(67)> Map.keys(map)
[:a, :b]
iex(68)> Map.values(map)
[1, 2]
iex(69)> Map.has_key?(map, :a)
true
iex(70)> map
%{a: 1, b: 2}
iex(71)> Map.delete(map, :a)
%{b: 2}
iex(72)> map
%{a: 1, b: 2}
iex(73)> a
[100, 200, 300]
iex(74)> i
** (RuntimeError) undefined function: i/0

iex(74)> i = 1
1
iex(75)> if i == 1 do
...(75)> puts "true"
...(75)> else
...(75)> puts "false"
...(75)> end
** (RuntimeError) undefined function: puts/1

iex(75)> if i == 1 do
...(75)> IO.puts "true"
...(75)> else
...(75)> IO.puts "false"
...(75)> end
true
:ok
iex(76)> i = 2
2
iex(77)> i
2
iex(78)> if i == 1 do
...(78)> IO.puts "true"
...(78)> else
...(78)> IO.puts "false"
...(78)> end
false
:ok
iex(79)> defmodule My do
...(79)>   def loop(0) do
...(79)>     IO.puts "done"
...(79)>   end
...(79)>   def loop(times) do
...(79)>     IO.puts "#{times} times remaining"
...(79)>     loop(times - 1)
...(79)>   end
...(79)> end
{:module, My,
 <<70, 79, 82, 49, 0, 0, 6, 8, 66, 69, 65, 77, 69, 120, 68, 99, 0, 0, 0, 115, 131, 104, 2, 100, 0, 14, 101, 108, 105, 120, 105, 114, 95, 100, 111, 99, 115, 95, 118, 49, 108, 0, 0, 0, 2, 104, 2, ...>>,
 {:loop, 1}}
iex(80)> My.loop(5)
5 times remaining
4 times remaining
3 times remaining
2 times remaining
1 times remaining
done
:ok
iex(86)> Enum.each([1, 2, 3], fn(i) ->
...(86)>   IO.puts(i)
...(86)> end)
1
2
3
:ok
iex(87)> Enum.each([1, 2, 3], &IO.puts/1)
1
2
3
:ok
iex(88)> Enum.filter([1,2,3,4,5], &rem(&1, 2) == 0)
[2, 4]
iex(89)> Enum.reject([1,2,3,4,5], &rem(&1, 2) == 0)
[1, 3, 5]
iex(90)> Enum.find([1,2,3,4,5], &rem(&1, 2) == 0)
2
iex(91)> Enum.member?([1,2,3,4,5], 3)
true
iex(92)> Enum.member?([1,2,3,4,5], 9)
false
iex(93)> Enum.any?([1,2,3,4,5,] &rem(&1, 2) == 0)
** (SyntaxError) iex:93: syntax error before: '&'

iex(93)> Enum.any?([1,2,3,4,5] &rem(&1, 2) == 0)
** (SyntaxError) iex:93: syntax error before: '&'

iex(93)> Enum.any?([1,2,3,4,5,], &rem(&1, 2) == 0)
true
iex(94)> [1,2,3,4,5]
[1, 2, 3, 4, 5]
iex(95)> [1,2,3,4,5,]
[1, 2, 3, 4, 5]
iex(96)> Enum.all?([1,2,3,4,5,], &rem(&1, 2) == 0)
false
iex(97)> Enum.count?([1,2,3,4,5,], &rem(&1, 2) == 0)
** (UndefinedFunctionError) undefined function: Enum.count?/2
    (elixir) Enum.count?([1, 2, 3, 4, 5], #Function<6.90072148/1 in :erl_eval.expr/5>)
iex(97)> Enum.count([1,2,3,4,5,], &rem(&1, 2) == 0)
2
iex(98)> Enum.max([1,2,3,4,5,], &rem(&1, 2) == 0)
** (UndefinedFunctionError) undefined function: Enum.max/2
    (elixir) Enum.max([1, 2, 3, 4, 5], #Function<6.90072148/1 in :erl_eval.expr/5>)
iex(98)> Enum.max([1,2,3,4,5,])
5
iex(99)> Enum.min([1,2,3,4,5,])
1
iex(100)> Enum.max_by([1,2,3,4,5,-9, -1], &abs/1)
-9
iex(101)> Enum.min_by([1,2,3,4,5,-9, -1], &abs/1)
1
iex(102)> Enum.sort([1, 02, 3, 4, 5])
[1, 2, 3, 4, 5]
iex(103)> Enum.sort([1, 02, -3, 4, 5])
[-3, 1, 2, 4, 5]
iex(104)> Enum.map([1, -2, 3, 4, -5], &abs/1)
[1, 2, 3, 4, 5]
iex(122)> def hoge do
...(122)>   "hoge"
...(122)> end
** (ArgumentError) cannot invoke def/2 outside module
    (elixir) lib/kernel.ex:3563: Kernel.assert_module_scope/3
    (elixir) lib/kernel.ex:2823: Kernel.define/4
    (elixir) expanding macro: Kernel.def/2
             iex:122: (file)
iex(122)> defmodule Foo do
...(122)>   def sum(x, y) do
...(122)>     x + y
...(122)>   end
...(122)> end
iex:122: warning: redefining module Foo
{:module, Foo,
 <<70, 79, 82, 49, 0, 0, 4, 140, 66, 69, 65, 77, 69, 120, 68, 99, 0, 0, 0, 123, 131, 104, 2, 100, 0, 14, 101, 108, 105, 120, 105, 114, 95, 100, 111, 99, 115, 95, 118, 49, 108, 0, 0, 0, 2, 104, 2, ...>>,
 {:sum, 2}}
iex(123)> import Foo
nil
iex(124)> sum(1, 2)
3
iex(122)> def hoge do
...(122)>   "hoge"
...(122)> end
** (ArgumentError) cannot invoke def/2 outside module
    (elixir) lib/kernel.ex:3563: Kernel.assert_module_scope/3
    (elixir) lib/kernel.ex:2823: Kernel.define/4
    (elixir) expanding macro: Kernel.def/2
             iex:122: (file)
iex(122)> defmodule Foo do
...(122)>   def sum(x, y) do
...(122)>     x + y
...(122)>   end
...(122)> end
iex:122: warning: redefining module Foo
{:module, Foo,
 <<70, 79, 82, 49, 0, 0, 4, 140, 66, 69, 65, 77, 69, 120, 68, 99, 0, 0, 0, 123, 131, 104, 2, 100, 0, 14, 101, 108, 105, 120, 105, 114, 95, 100, 111, 99, 115, 95, 118, 49, 108, 0, 0, 0, 2, 104, 2, ...>>,
 {:sum, 2}}
iex(123)> import Foo
nil
iex(124)> sum(1, 2)
3
iex(125)> File.write("tmp.txt", "hello hello")
:ok
iex(126)> {:ok, str} = File.read("tmp.txt")
{:ok, "hello hello"}
iex(127)> str
"hello hello"
iex(128)> {:ok, str} = File.read("tmp2.txt")
** (MatchError) no match of right hand side value: {:error, :enoent}

iex(128)> str
"hello hello"
iex(153)> System.argv
[]
iex(154)> IO.inspect(System.argv)
[]
[]
iex(156)> unless i == 2
** (RuntimeError) undefined function: unless/1

iex(156)> unless i == 2 do
...(156)>   IO.puts "true"
...(156)> else
...(156)>   IO.puts "false"
...(156)> end
false
:ok
iex(157)> i
2
iex(159)> add = fn(a, b) -> a + b end
#Function<12.90072148/2 in :erl_eval.expr/5>
iex(160)> add(2, 3)
** (RuntimeError) undefined function: add/2

iex(160)> add.(2, 3)
5
iex(161)> list = [1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
iex(162)> filtered = Enum.filter(list, fn(e) -> e * 10 end)
[1, 2, 3, 4, 5]
iex(163)> filtered = Enum.filter(list, fn(e) -> e < 4 end)
[1, 2, 3]
iex(164)> Enum.map(filtered, fn(e) -> e * 10 end)
[10, 20, 30]
iex(165)> [1,2,3,4,5]
[1, 2, 3, 4, 5]
iex(166)> [1,2,3,4,5] |> Enum.filter(fn(e) -> e < 4 end) |> Enum.map(fn(e) -> e * 10 end)
[10, 20, 30]
iex(167)> [1,2,3,4,5] |> Enum.filter(&(&1 < 4)) |> Enum.map(&(&1 * 10))
[10, 20, 30]