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…あまり気持ちのいいものではないですよね。