概要

今日は Ruby の ぼっち演算子(&. について学んだ。

正式名称は safe navigation operator(安全なナビゲーション演算子) で、Ruby 2.3 で導入された。

nil かもしれないオブジェクトに対してメソッドを呼び出すとき、NoMethodError を防ぐための演算子。


問題:nil に対してメソッドを呼ぶとエラーになる

user = nil

user.name  # => NoMethodError: undefined method `name' for nil

usernil のとき、.name を呼び出すと Ruby はエラーを投げる。


ぼっち演算子で解決

user = nil

user&.name  # => nil(エラーにならない)

&. を使うと、レシーバ(. の左側)が nil のとき エラーにせず nil を返す だけ。

オブジェクトが存在するときは、普通のメソッド呼び出しと同じ動作をする。

user = User.find(1)  # ユーザーが存在する場合

user&.name  # => "田中 太郎"(普通に呼び出される)

なぜ「ぼっち」?

&. の見た目が、一人でポツンと座っている人の後ろ姿に見えることから、日本の Ruby コミュニティで「ぼっち演算子」と呼ばれるようになった。& が頭、. がお尻のイメージ。

英語圏では lonely operator と呼ばれることもある。


コードで比較

ぼっち演算子を使わない場合、こう書く必要があった。

# 方法1:nil チェック
name = user.nil? ? nil : user.name

# 方法2:&&(ダブルアンド)
name = user && user.name

ぼっち演算子を使うと、シンプルに書ける。

# ぼっち演算子
name = user&.name

JSONカラムのような「存在するかわからないキー」の取り出し

データベースの JSON カラムなど、値が nil になりうるケースで特によく使われる。

# settings が nil の場合にエラーにならない
settings&.[]('theme')  # => nil

# settings が存在する場合
settings = { 'theme' => 'dark', 'language' => 'ja' }
settings&.[]('theme')  # => "dark"

.[]('キー名') はハッシュからキーを取り出す書き方で、hash['キー名'] と同じ意味。


チェーン(連鎖)もできる

# user か company が nil なら nil を返す
city = user&.company&.address&.city

途中で nil が出た時点でそこで止まり、残りは評価しない。


注意点

ぼっち演算子は「nil のとき nil を返す」だけ

false のときは通常通りメソッドを呼び出す。nil だけを特別扱いしている。

obj = false
obj&.to_s  # => "false"(false はメソッドを呼び出せる)

使いすぎに注意

nil が来るはずのない場所でぼっち演算子を使うと、バグが隠れてしまうことがある。

# user は必ず存在するはずなのに &. を使ってしまうと
# nil が来てもエラーにならず気づけない
user&.name  # 本当は user.name で良い

nil になる可能性がある場所だけで使うのが基本。


まとめ

状況 動作
レシーバが nil nil を返す(エラーなし)
レシーバが nil 以外 通常のメソッド呼び出しと同じ
false のとき 通常のメソッド呼び出し(nil 扱いしない)
  • &.nil のときだけ エラーを防いで nil を返す
  • チェーンして複数つなげることもできる
  • nil になりうる場所にだけ使うのが正しい使い方

参考文献