タイトルを英語にすると and and && and &&=
という訳のわからないことになります。日本語って便利ですね。
今まで意識して使っていなかったand
&&
と、ついでに&&=
が、使い分けるとちょっと便利そうという覚書。
たとえば
a = 1
b = 2 and a and a < b #=> true
c = 2 && a && a < c #=> ArgumentError: comparison of Fixnum with nil failed
puts b #=> 2
(d = 2) && a && a < d #=> true
puts d #=> 2
という動作からもわかるようにand
って=
よりも後に解釈されるらしい。ずっと&&と同じものだと思ってました。
リファレンスを見ると確かにandとorの優先度は一番低いみたいですね。
上の例だとbとdでは最終的な結果は同じ(変数xに2を代入し、変数aがあるならば大小を比べる)なのですが、bの方が少し見やすい。
他にも例えば
1..3 && 5 #=> 1..5
1..3 and 5 #=> 5
nil && 2 ? :a : :b #=> :b
nil and 2 ? :a : :b #=> nil
みたいな違いがあります。
Railsなんかで一つのアクション中で複数のrenderをする場合は、renderの後にreturnを行わないとdouble render errorが発生しますが、
if sub_acsion = :hoge
render :hoge_page and return
end
render :nomal_page
と書くといいよというのも、Railsの何かのドキュメントに載っていました。and
を使うことでrender :hoge_page
が解釈されたあとにreturnされています。
ついでに言うと!
とnot
の優先度もかなり違う……知らないと、稀によく嵌りそうですね
話はかわりますが
# xが未定義なら初期値を1とする
x ||= 1
というように||=
を使っているソースはよく見かけます。
一方で&&=
って何に使うんじゃ、と思っていたのですが、最近こんなソースを見かけました。
def validate_params
success = true
success &&= validate_time(param[:time]) if param[:time]
success &&= validate_date(param[:date]) if param[:date]
success
end
「値が設定されているなら、かつその値の整合性チェックをする」というのを複数の値に対して行いたい時に&&=
は結構役に立ちそうです。