ham-capのブログ

プログラミング学習の記録

【Ruby】ぼっち演算子でNoMethodErrorを回避する

ぼっち演算子とは何か

Ruby2.3から実装された機能で、るりまの説明によると

safe navigation operator (ぼっち演算子): object&.foo という形式のメソッド呼び出し形式が追加されました。これは object が nil でないときにメソッド foo を呼び出します。 Active Support の try! と似ていますが、メソッド名は文法的に必須であるという点が異なります。

出典:https://docs.ruby-lang.org/ja/latest/doc/news=2f2_3_0.html

とのこと。

「objectがnilでないときにメソッドfooを呼び出します」ということは、レシーバがnilの場合のみ、続くメソッドを呼び出さずにそのままnilを返すということになります。

これを使うと何がうれしいかというと、メソッド呼び出し時のレシーバがnilの場合でもNoMethodErrorを発生させずに処理を続けられる、という点です。

使い方は通常のメソッド呼び出しで使用する.と同じです。

使いどころ

例えば、ある変数をレシーバとしてメソッドチェーンで処理を実行する際、その変数の中身が何らかのクラスから生成されたインスタンスの場合とnilの場合どちらもあり得るという状況だとします。

そういった状況で且つ、nilの場合であってもNoMethodErrorにしたくない(nilでも構わない)というような場合にぼっち演算子が便利です。

例えば、DBから取得したユーザーを変数@userに格納し、.idのようなアクセサメソッドでユーザーIDを返して別のメソッドの引数として渡すような処理をしたいとします。 もし、この引数に渡るのがユーザーIDであれnilであれ、どちらでも問題ないということであれば、存在しないユーザーを取得しようとして@usernilが入ったときに.idNoMethodErrorで止まってしまうと困るわけです。

かと言って、わざわざ条件分岐をしたりするのも無駄に複雑になるだけです。

そんな時に、以下のように&.を使うことで、レシーバがnilの場合には続くメソッドを無視してNoMethodErrorを回避できます。

@user&.id

ただし、いくら&.を使ったところで、レシーバがnil以外の場合にメソッド名をタイポしていたりすると当然NoMethodErrorとなりますので注意が必要です。

まとめ

ちょっとした機能ではありますが、これがあるだけで条件分岐を減らすことができる場面がけっこうあると思います。

そういう場面でスッと思い出せるように覚えておきたいものです。

今回は以上になります。