概要
原著者の許諾を得て翻訳・公開いたします。
- 英語記事: Safe navigation operator in Ruby
- 原文公開日: 2017/11/17
- 著者: Akshay Mohite
Rubyのぼっち演算子はRailsのObject#try
より高速(翻訳)
&.
というsafe navigation演算子(Null条件演算子: Rubyでは「ぼっち演算子」とも呼ばれます)はRuby 2.3で導入されました。この演算子は、nil
オブジェクトに対してメソッドが呼び出されたときにnil
を返します。この演算子がなかったときは、nil
オブジェクトに対して呼び出しを行うと以下のようにエラーになりました。
nil.some_method
#=> NoMethodError: undefined method 'some_method' for nil:NilClass
safe navigationが必要な理由
入力値が正しくない場合にオブジェクトを取得できないことは非常によくあります。このような場合、オブジェクトが取れることを期待してメソッド呼び出しを続行すると、オブジェクトがnil
の場合に動かなくなるかもしれません。
safe navigationはこうした状況を避けるために導入されました。これを用いて、呼び出すオブジェクトがnil
であってもコードが動き続けるようにできます。safe navigationは、メソッド呼び出しが失敗したときにnil
オブジェクトを受け取ってもよい場合に使うべきです。
ActiveSupportのtry
RailsではActiveSupportの#try
メソッドが利用でき、上述のsafe navigationと似ています。メソッド名からわかるように、#try
はそのオブジェクトが利用可能な場合にメソッド呼び出しを試みます。nil
オブジェクトに対してメソッド呼び出しが行われようとすると、エラーではなくnil
を返します。
nil.try(:some_method)
#=> nil
Ruby 2.3のsafe navigation
オブジェクトがnil
かどうかわからない場合は、たとえば以下のようにメソッド呼び出しの前にアンパサンド&
を追加するだけで使えます。
nil&.some_method
#=> nil
上のコードは例外をスローせずにnil
を返します。
このコードは次のコードと同等です。
nil ? nil.some_method : nil
つまりオブジェクトがtrue
と評価されればオブジェクトに対してメソッドを呼び出し、false
と評価されればnil
を返します。
#try
とsafe navigationのどっちを使うか
Railsで仕事をすることが多い人は#try
を常用していることでしょう。#try
とsafe navigation演算子&.
のパフォーマンスを比較してみると、Rubyでサポートされているsafe navigation演算子の方が遥かに高速で、しかもActiveSupportなどRailsの機能に依存しません。