いる 黄色 エネルギーアモ 緑 ヘビーアモ ヘムロックバースト フラットライン スピットファイア 使わない オレンジ ライトアモ 紫 スナイパーアモ 赤 ショットガンアモ
Elixirでパイプ中にpryでデバッグしたい
環境
- Elixir 1.x
コード
Elixirのパイプ演算子便利なんだけど、途中の変数変化を把握しづらい。そこでpryを使ってブレークポイントを仕掛ける。
defmodule Example do def pipe do 1..10 |> Enum.map(&(&1 * &1)) |> Enum.filter(&rem(&1, 2) == 0) |> (fn(x) -> IEx.pry;x end).() |> Enum.take(3) end end
実行
iex(1)> c "index.ex" warning: redefining module Example (current version defined in memory) index.ex:10 [Example] iex(2)> Example.pipe Break reached: Example.pipe/0 (index.ex:15) 13: |> Enum.map(&(&1 * &1)) 14: |> Enum.filter(&rem(&1, 2) == 0) 15: |> (fn(x) -> IEx.pry;x end).() 16: |> Enum.take(3) 17: end pry(1)> x [4, 16, 36, 64, 100] pry(2)> respawn Interactive Elixir (1.6.6) - press Ctrl+C to exit (type h() ENTER for help) [4, 16, 36]
パイプ演算子中ではない場合
require IEx; defmodule Example do def add(x, y) do IEx.pry x + y end end
Elixirでファイルの読み書きまとめ
環境
- Elixir 1.x
基本的な読み書き
File.write/2
で書き込み、 File.read/1
で読み込みできる。
iex> File.write "sample.txt", "Hello" :ok iex> File.read "sample.txt" {:ok, "Hello"}
読み込んだときに2要素のタプルを返してくるのがポイント
こういう感じで分岐できる
case File.read("sample.txt") do {:ok, content} -> IO.inspect content {:error, reason} -> IO.puts "error: #{reason}" end
追記したい
第三引数に append を渡す
iex> File.write "sample.txt", "Hello" :ok iex> File.write "sample.txt", " World", [:append] :ok iex> File.read "sample.txt"
エラー時に例外を発生させたい
関数名の最後にビックリマークをつける
iex> File.read! "404.txt" ** (File.Error) could not read file "404.txt": no such file or directory (elixir) lib/file.ex:310: File.read!/1
ElixirでFizzBuzz
condを使う場合
defmodule FizzBuzz do def upto(n) do cond do rem(n, 15) == 0 -> "FizzBuzz" rem(n, 3) == 0 -> "Fizz" rem(n, 5) == 0 -> "Buzz" true -> n end end end for n <- 1..100 do IO.puts FizzBuzz.upto(n) end
パターンマッチを使う場合
defmodule FizzBuzz do def upto(n) when rem(n, 15) == 0, do: "FizzBuzz" def upto(n) when rem(n, 3) == 0, do: "Fizz" def upto(n) when rem(n, 5) == 0, do: "Buzz" def upto(n), do: n end for n <- 1..100 do IO.puts FizzBuzz.upto(n) end
参考リンク
Elixirで関数呼び出し時にドットを付ける/付けないの違い
環境
- Elixir 1.x
結論
- 無名関数の場合はドット(.)が必要
- 名前付き関数の場合は不要
違いについて
他の言語やったあとにElixirやってると以下のようなエラーをよく起こす。
iex(1)> add = fn a, b -> a + b end #Function<12.99386804/2 in :erl_eval.expr/5> iex(2)> add(1, 2) ** (CompileError) iex:2: undefined function add/2
実際には以下が正しい。
iex(2)> add.(1, 2) 3
つまり関数呼び出し時にドットが抜けてたのだが、ドットを付けない場合もある。どういう違いがあるのか気になった。
利害は結構単純で、fnからendのキーワードを使って定義された関数は無名関数と呼ばれ、名前の通り関数名がない。
一方、defからendのキーワードで定義された関数は普通?の関数、名前付き関数になり、名前付き関数を呼び出す場合はドットを付けない。
defmodule Mymodule do def add(a, b) do a + b end end IO.puts Mymodule.add(1, 2)
逆にドットを付けて実行するとエラーになる。気をつけよう
Mymodule.add.(1, 2) ** (UndefinedFunctionError) function Mymodule.add/0 is undefined or private. Did you mean one of: * add/2 Mymodule.add() hoge.exs:28: (file) (elixir) lib/code.ex:677: Code.require_file/2