考えてみればそのとおりだけども、ちょっとハマったのでメモがてら。
ぼっち演算子についてはsafe navigation operator (ぼっち演算子)を参照。
rubyのぼっち演算子が便利なのでよく使うのですが、
条件分岐させるときに注意が必要です。
# hogeはnameというインスタンス変数を持つオブジェクトとします
hoge.name.blank? ? '空です' : '空じゃないです'
みたいな判定のときに
hoge.name = '値あり'
hoge.name&.blank? ? '空です' : '空じゃないです'
#=> '空じゃないです'
hoge.name = ''
hoge.name&.blank? ? '空です' : '空じゃないです'
#=> '空です'
hoge.name = nil
hoge.name&.blank? ? '空です' : '空じゃないです'
#=> '空じゃないです' # 思ってたのと違う!!
のようにname
がnilのときに期待と逆の結果になります。
ぼっち演算子は「オブジェクトがnilじゃないときにメソッドを呼び出す」という動きなので、
nilのときはblank?
を呼び出さないためnilが返り、nilはfalsyなのでfalseのときの結果を返します。
そもそもnil?
もblank?
もnilが使えるメソッドなので素直に
hoge.name.blank? ? '空です' : '空じゃないです'
と書けばOKです。
empty?
はnilが持ってないので、ぼっち演算子が必須ですが、
hoge.name&.empty? ? '空です' : '空じゃないです'
だと、hoge.nameがnilのときは「空じゃないです」が返って、ブランクのときは「空です」が返るという直感的じゃない動きをします。
empty?
使うときってnilチェックしているかと思うのでこの罠には引っかからないかと思いますが。
ちなみにpresent?
だと、結果オーライな感じになります。
hoge.name = '値あり'
hoge.name&.present? ? '空じゃないです' : '空です'
#=> '空じゃないです'
hoge.name = ''
hoge.name&.present? ? '空じゃないです' : '空です'
#=> '空です'
hoge.name = nil
hoge.name&.present? ? '空じゃないです' : '空です'
#=> '空です'
&
ひとつだけの違いだし、パッと見で気づきにくいのでレビューで見落としがちだったりします。
あらためてrspecとか大事だなと思いました。