2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Ruby アンパサンドを用いた安全参照演算子(&.)とは

Last updated at Posted at 2020-10-22

#はじめに

変数が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 追記]
コメント欄にて、条件1falseのときは使えないというご指摘をいただきましたので、修正します。失礼いたしました。。

これを応用して、上記の例を用いて説明すると、以下のように書けます。

ary = [[1,2,3],nil,[5,6]]

ary.each do |element_ary|
  p element_ary && element_ary.length
end

element_arynilが入ると[条件1]の時点で、論理演算子の処理が終わり、nilを返すので、[条件2]lengthメソッドにnilが渡ることはありません。

これを省略して以下のように、オブジェクトの後に&をつけることでも表現できるのが、安全参照演算子と呼ばれるものだったのです。

ary = [[1,2,3],nil,[5,6]]

ary.each do |element_ary|
  p element_ary&.length
end

#おわりに
論理演算子の応用例ということでしたが、あたまいいなあと思いました。

2
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?