Edited at

Elixirで中置演算子マクロ (Re: Elixirでもtryがしたい!)

More than 3 years have passed since last update.

Elixirでもtryがしたい! を読んで試してみたくなったので調べてみました。

NilClassが無い以上、try的な物を生やすのは諦めて、中置演算子なら見た目近いかなーということでパイプを置き換えてみます。

defmodule Attempt do

defmacro left ~> right do
quote do
case unquote(left) do
nil -> nil
other -> unquote(Macro.pipe(quote(do: other), right, 0))
end
end
end
end

iex(1)> defmodule Attempt do

...(1)> defmacro left ~> right do
...(1)> quote do
...(1)> case unquote(left) do
...(1)> nil -> nil
...(1)> other -> unquote(Macro.pipe(quote(do: other), right, 0))
...(1)> end
...(1)> end
...(1)> end
...(1)> end
{:module, Attempt,
<<70, 79, 82, 49, 0, 0, 5, 240, 66, 69, 65, 77, 69, 120, 68, 99, 0, 0, 0, 168, 131, 104, 2, 100, 0, 14, 101, 108, 105, 120, 105, 114, 95, 100, 111, 99, 115, 95, 118, 49, 108, 0, 0, 0, 4, 104, 2, ...>>,
{:~>, 2}}
iex(2)> import Attempt
nil
iex(3)> 1 ~> Integer.to_string
"1"
iex(4)> nil ~> Integer.to_string
nil
iex(5)>

ちなみにElixirの中置演算子は使える記号が限られていて、今のところ

http://www.rodneyfolz.com/custom-infix-functions-in-elixir/

\\, <-, |, ~>>, <<~, ~>, <~, <~>, <|>, <<<, >>>, |||, &&&, and ^^^.との事。例えば|<を定義しようとすると** (SyntaxError) iex:7: syntax error before: '<'で怒られました。

或いはpipespectのように

  import Kernel, except: [{:|>, 2}]

defmacro first |> rest do

Kernelからexcept…あまり気持ちのいいものではないですよね。