#はじめに
変数がnil
の時、メソッドによってはエラーを起こすものがあったりします。
例えば、なんかの処理で値を配列に詰めたものをeach
で回したりするときに、もしnil
が入ってたりすると、処理が止まってエラーが出る。。なんてことが起こると困りますよね。
そんなときはガード節(関数や繰り返し処理の最初に例外を取り除くように実装する方法)を使ってnext if [変数].nil?
とやって、nil
を回避できたりするんですが、論理演算子を応用した別の方法があるときいて、メモしていきたいと思います。
#アンパサンド(&)を用いた安全参照演算子
最初に結論から申しますと、[オブジェクト]&.[メソッド]
というかたちで書きます。
例えば、
#&を使わないと
ary = [[1,2,3],nil,[5,6]]
ary.each do |element_ary|
p element_ary.length
end
#=>
#3
#Traceback (most recent call last):
# 2: from test.rb:3:in `<main>'
# 1: from test.rb:3:in `each'
#test.rb:4:in `block in <main>': undefined method `length' for #nil:NilClass (NoMethodError)
#&を使うと
ary = [[1,2,3],nil,[5,6]]
ary.each do |element_ary|
puts element_ary&.length
end
#=>
#3
#nil
#2
このように、エラーがおきません。
#原理
実はこれ、論理演算子&&
が関係しています。
一般的に、論理演算子は以下の特徴を持ってます。
・左から順に評価される
・論理式の真偽が決まると、残りの式は評価されない
・最後に評価された式の値が論理全体の値となる
つまり、[条件1] && [条件2]
とあったとき、[条件2]
は[条件1]
が真のときにのみ、評価されます。[条件1]
がnil
~~もしくはfalse
~~であった場合、条件2を評価するまでもなく、論理演算子&&
の結果はnil
~~もしくはfalse
~~になるからです。
[2020/10/27 追記]
コメント欄にて、条件1
がfalse
のときは使えないというご指摘をいただきましたので、修正します。失礼いたしました。。
これを応用して、上記の例を用いて説明すると、以下のように書けます。
ary = [[1,2,3],nil,[5,6]]
ary.each do |element_ary|
p element_ary && element_ary.length
end
element_ary
にnil
が入ると[条件1]
の時点で、論理演算子の処理が終わり、nil
を返すので、[条件2]
のlength
メソッドにnil
が渡ることはありません。
これを省略して以下のように、オブジェクトの後に&
をつけることでも表現できるのが、安全参照演算子と呼ばれるものだったのです。
ary = [[1,2,3],nil,[5,6]]
ary.each do |element_ary|
p element_ary&.length
end
#おわりに
論理演算子の応用例ということでしたが、あたまいいなあと思いました。