こんにちは!
プログラミング未経験文系出身、Elixirの国に迷い込んだ?!見習いアルケミストのaliceと申します。
今回はElixirの教科書『プログラミングElixir』第4章を読んで、学んだことをまとめます。1
実行環境
Windows 11 + WSL2 + Ubuntu 22.04
Elixir v1.14.3
Erlang v25.0.4
以下私が詰まった箇所です。
それ以外は本書かElixir公式の学習ページか、Elixir Schoolかで、学ぶことができます。
前提条件
以下のソースコード内で出現する#=>
とは、「実行結果」を指します。
4.1 組み込みの型
組み込み、というくらいだからオリジナルの型が別に作れるのかな?
4.2 値型
整数(integer)
最大値はない。
iex()> 1234 #10進数
1234 #10進数
iex()> 0b1010 #2進数
10 #10進数
iex()> 0o765 #8進数
501 #10進数
iex()> 0xcafe #16進数
51966 #10進数
10進数と区別するため
2進数: 0b
8進数: 0o
16進数: 0x
を頭につける
正規表現(regular-expression)
メタ文字の扱い方についてのルールは、PCREに準拠し、Regexモジュールで管理される。
iex()> Regex.run ~r{[a]}, "elephant"
["a"] #"elephant"に"a"が含まれるかどうかの検索
iex()> Regex.run ~r{[u]}, "elephant"
nil #"elephant"に"u"が含まれるかどうかの検索
iex()> Regex.run ~r{[aeiou]}, "caterpillar"
["a"] #"caterpillar"に"aeiou"のいずれかが含まれるかどうかの検索
#"caterpillar"の先頭文字から検索するため、最初にヒットしたaが返される
iex()> Regex.scan ~r{[aeiou]}, "caterpillar"
[["a"], ["e"], ["i"], ["a"]]
#"caterpillar"に"aeiou"のいずれかが含まれるかどうかの検索
#scanは"caterpillar"の先頭文字から順にヒットした値全てを返す
iex()> Regex.run ~r{![a]}, "caterpillar"
nil #"caterpillar"に"a"が含まれないかどうかの検索
iex()> Regex.run ~r{^[r]}, "caterpillar"
nil #"caterpillar"の頭文字が"r"がであるかどうかの検索
iex()> Regex.run ~r{[r]$}, "caterpillar"
["r"] #"caterpillar"の末尾が"r"がであるかどうかの検索
...面白いんで無限にやれそうだけど次(;^ω^)
4.3 システム型
特筆すべき箇所なし
4.4 コレクション型
リスト(list)
iex()> [1, "ant", 5.2, "human"] -- ["ant"]
[1, 5.2, "human"] #"ant"をリストから除外する
iex()> [1, "ant", 5.2, "human"] -- [1]
["ant", 5.2, "human"] #1をリストから除外する
iex()> [1, "ant", 5.2, "human"] -- [5]
[1, "ant", 5.2, "human"] #5をリストから除外する(5.2と5は違うので除外されない)
時折、型宣言が不要なことや、複数の型が同じリストに入れられることに改めて感動する。
4.5 マップ(Map)
マップを作成する ※同じ名前のマップを作成すると順次上書きされ、最新のものだけが保持される
※キー(左辺)、バリュー(右辺)ともに型は問わない(文字列、アトム、タプルどれでも問題ない)
iex()> numbers = %{"one" => 1, :two => 2, {1,1,1} => 3}
%{:two => 2, {1, 1, 1} => 3, "one" => 1}
iex()> numbers = %{1 => "one", 2 => :two, 3 => {1,1,1}}
%{1 => "one", 2 => :two, 3 => {1, 1, 1}}
iex()> numbers = %{:one => "one", {1,2} => :two, "three" => 3}
%{:one => "one", {1, 2} => :two, "three" => 3}
マップのキーからバリューを呼び出す
iex()> numbers["three"] #numbersマップのキーが"three"を呼び出す
3
iex()> numbers[3] #numbersマップのキーが3を呼び出す(ヒットなし)
nil
iex()> numbers[:one]
"one"
iex()> numbers.one #キーがアトムの場合、こうも呼べる(ドット記法)
"one"
キーは一意、バリューは重複可
iex()> fruits = %{1 => "apple", 2 => "apple"}
%{1 => "apple", 2 => "apple"}
iex()> fruits[1]
"apple"
iex()> fruits[2]
"apple"
iex()> another_fruits = %{1 => "apple", 1 => "peach", 3 => "banana"}
warning: key 1 will be overridden in map #マップを作成する段階で同じキーに違うバリューを充てようとすると警告される
%{1 => "peach", 3 => "banana"}
iex()> another_fruits = %{1 => "melon"}
%{1 => "melon"} #一方、マップを作成した後で同じキーに違うバリューを充てようとすると警告なしで上書きされる
iex()> another_fruits[1]
"melon"
4.6 日付と時間
シジル(sigil)とは、~(チルダ)から始まるもの。
シジル?シギル?たまに表記ゆれがあるようだ。
詳しくはこちらを参照↓
~Tは時刻型を示すシジル。
iex()> {:ok, t1} = Time.new(12, 30, 00) #=> {:ok, ~T[12:30:00]}
iex()> Time.add(t1, 3600) #=> ~T[13:30:00]
Time.addのドキュメントを見ると分かるが、Time.addの第二引数の単位はデフォルト値では「秒」で評価される。
3600秒 = 1時間。
4.7 名前、ソースファイル、慣習、演算子など 以降
特筆すべき箇所なし
余談:『プログラミングElixir』は第4章から読むこと
第2章で詰まっていたところそう教わりました。
第2章と第3章を含め、頭から読んだ場合、Elixirのエッセンスというか「ここがすごい」というのを語ってあるので分かる人は感動するらしい...。
しかし、私のような初学者の場合は逆に「何を言っているのか全然分からない(;^ω^)」となってしまった。
技術書はわからない箇所はとばす。全体を通読することがまず大事。
後から戻ってきたら点が線になる日がきっと来る。
~Elixirの国のご案内~
※Elixirって何ぞや?と思ったらこちらもどぞ。未来がぎゅっと詰まった、Elixirは今年で生まれて10周年です
We Are The Alchemists, my friends!2
Elixirコミュニティは本当に優しくて温かい人たちばかり!
私が挫折せずにいられるのもこの恵まれた環境のおかげです。
まずは気軽に話しかけてみてください。3
-
プログラミングが完全未経験ゆえ、「え?!そこからつまずく?!!」というお見苦しい箇所があるかと思いますが、私自身の記録のために残します。ご了承ください。 ↩
-
@torifukukaiouさんのAwesomeな名言をお借りしました。Elixirコミュニティを一言で表すと、これに尽きます。 ↩