Ruby の &. と #try の違い
Ruby 2.3 で Safe Navigation Operator(&.
)という新しい演算子が追加されました。
これは obj&.to_i
という風にメソッド呼び出しのように使い、レシーバが nil
の場合に nil
を返します。
10&.to_s # => "10" nil&.to_s # nil
このように nil
チェックすることなく安全にメソッドを呼び出すことが出来ます。
#try
Rails の ActiveSupport にも #try
という似たようなメソッドが定義されています。
これはレシーバがメソッドが呼びだせる場合にそのメソッドを呼び出すというような処理になります。
また、レシーバが nil
の場合は必ず nil
を返します。
10.try(:to_s) # => "10" nil.try(:to_s) # => nil
&.
と #try
の違い
両方とも『レシーバが nil
ではない場合にメソッドを呼び出す』という目的なんですが、具体的な挙動は少し違っています。
&.
が『nilでない場合にメソッドを呼び出す』のに対して、#try
は『メソッドを呼び出すことができるときにメソッドを呼び出す』というような挙動になります。
どういうことかというと
# 10 には #hoge メソッドは定義されていない(呼び出せない)ので nil を返す 10.try(:hoge) # => nil # レシーバは nil ではないので #hoge メソッドを呼びだそうとするが # #hoge メソッドは定義されてないのでエラー 10&.hoge # => Error: undefined method `hoge' for 10:Fixnum (NoMethodError)
というような挙動になります。
これは #try
が respond_to?
を使用して『メソッドを呼びだせるかどうか』をチェックしているためです。
このような違いがあるため &.
を #try
の代替として使用する場合は注意して使用する必要があります。
共通の挙動
#try
も &.
もレシーバが nil
の場合は nil
しか返しません。
nil&.nil? # => nil nil.try(:nil?) # => nil