Edited at

Elixirでもtryがしたい!

More than 3 years have passed since last update.

railsタグに釣られたそこのあなた!elixirを少しやってみませんか!?

Regex.runがマッチしない時nilを返すのでついカッとなって書いた反省はしていない

rubyist(rails使ってる人だけ?)にはお馴染みのtryと同じようなことがしたいので作ってみました。

ruby(rails)のtryを知らない方のために説明すると、「nilなら何もせずにnilを返して、nilでなければ与えられた処理をするメソッド」です。非常にシンプルなので実装を見たほうが分かりやすいと思います。


作る

すでにKernel.SpecialForms.tryという関数があるので、とりあえずattemptという名前にします(短くて良いネーミング緩募)

defmodule Attempt do

def attempt val, fun do
unless is_nil val do
fun.(val)
end
end
end


使ってみる

before

> 25 |> Integer.to_string

"25"
> nil |> Integer.to_string
** (ArgumentError) argument error
:erlang.integer_to_binary(nil)

nilにInteger.to_stringを適用しようとして悲しいことになっています。

after

> import Attempt

> 25 |> attempt(&Integer.to_string/1)
"25"
> nil |> attempt(&Integer.to_string/1)
nil

良い感じですね。パイプラインと&が良い仕事しています。パイプライン万歳。

マクロにできそうな気がするけど、マクロがよく分かってないのでマクロ版はそのうち。


おまけ

railsタグが付いているのにelixirの話を読まされてご立腹の方のためにrubyの小ネタをば。

def double a

a * 2
end

2.try(&method(:double)) #=> 4

オブジェクトのメソッドならば& + シンボルでブロックの代わりになることは有名ですが、名前空間なしで呼び出せるメソッド(同じクラスのメソッドとかKernelのメソッド)の場合はmethodメソッドを使うことで&を使って書くことができます。