今回はRailsのエラーハンドリングで役立つぼっち演算子(.&)とtry、try!メソッドについて紹介したいと思います。ぼっち演算子(.&)やtry、try!メソッドを用いることで、レシーバーがnilだった場合の処理をシンプルに記載することができるためとても便利です。
ぼっち演算子(.&)とは
ぼっち演算子とは、レシーバーがnilだった場合にNoMethodErrorを返さず、nilを返してくれる機能になります。ぼっち演算子はRuby2.3で実装された機能で「&.」と記述することができます。
使い方
例えば、以下のようなユーザーの名前を取得するコードがあるとします。
user.name
userがnilだった場合、NoMethodErrorエラーが出力されてしまいます。
user.name
=> NoMethodError (undefined method `name' for nil:NilClass)
一方でぼっち演算子を使用すると、エラーを出力せずnilを返してくれるようになります。
user&.name
=> nil
ぼっち演算子を使うと何が良いのか
例えばuserがnilではなかった場合、そのuserの名前を出力したいとします。
この場合、何も考えずに書くと以下のようなコードになります。たったこれだけの処理で3行も記述されてしまっていますね。
unless user.nil?
user.name
end
しかし上記のような処理の場合、ぼっち演算子を用いることで以下のようなシンプルなコードに修正することができます。
user&.name
このようにぼっち演算子を用いることで、レシーバーがnilかどうかで条件分岐しなくて済むためコード量を抑えることができます。
注意点
ぼっち演算子を用いることでエラーではなくnilを返すことができますが、メソッドがそもそも存在しない場合(定義されていない場合)は変わらずエラーを返してしまいます。
# メソッドが存在しない場合
"user"&.name
=> NoMethodError (undefined method `name' for "user":String)
tryメソッドとは
tryメソッドとは、レシーバーがnilだった場合やメソッドが存在しない(定義されていない)場合に、NoMethodErrorを返さずnilを返してくれるメソッドになります。
# userがnilだった場合
user.try(:name)
=> nil
# userが存在しない場合
"user".try(:name)
=> nil
try!メソッドとは
try!メソッドとは、レシーバーがnilだった場合にNoMethodErrorを返さず、nilを返してくれるメソッドになります。お気づきかもしれませんが、ぼっち演算子と同じ機能になります。
# userがnilだった場合
user.try!(:name)
=> nil
# userが存在しない場合
"user".try(:name)
=> NoMethodError (undefined method `name' for "user":String)
結局どれを使えば良いのか
ここまででぼっち演算子とtry、try!メソッドの3つについて紹介しました。どれも似たような機能でしたが、実際にはどれを使えば良いのでしょうか。
結論、ぼっち演算子を使用するようにしましょう。
理由としては以下になります。
- メソッドが定義されてないことによるNoMethodErrorを検知してくれる
- tryとtry!メソッドはRails環境、ぼっち演算子はRuby環境のため、ぼっち演算子の方が汎用性が広い
- tryやtry!よりもぼっち演算子の方が処理速度が速い
一見するとエラーを出力しないtryメソッドが最適解のように見えますが、「エラーを吐き出さず全てnilで返す = バグに気がつかない」といった場面が想定されます。そのため、tryメソッドの使用はできるだけ避けた方が無難です。
まとめ
- ぼっち演算子とは、レシーバーがnilだった場合にNoMethodErrorを返さずnilを返してくれる機能
- tryメソッドとは、レシーバーがnilだった場合やメソッドが存在しない(定義されていない)場合に、NoMethodErrorを返さずnilを返してくれるメソッド
- try!メソッドとは、レシーバーがnilだった場合にNoMethodErrorを返さずnilを返してくれるメソッド
参考
今回はRailsのエラーハンドリングで役立つぼっち演算子(.&)とtry、try!メソッドについて紹介しました。nilで条件分岐する「user.name if user.present?」のような冗長な記述をしている箇所は、ぼっち演算子(.&)に置き換えるよう修正しましょう。