Rubyの短絡評価 &&, ||
結論
&&は左側がtrueだと右側を評価する / 左側がfalseだと右を評価せずfalseを返す
||は左側がtrueだとその時点で左側を実行する / 左がfalseだと、右側を評価する
&&: AND演算子
code: .rb
# 左側の値がfalseの場合、その時点で右側を評価をせずに、falseを返す。
false && "a"
=> false
# 左側がtrueの場合、右側も評価して実行する。
true && "a"
=> "a" # 右側が返ってる
true && nil
=> nil # 右側が実行されてる
true && (raise "failed")
=> raise "failed" が実行される
||: OR演算子
code: .rb
# 左側の式が true の場合、右側の式は評価せず、左側を返す・実行する
"a" || "b"
=> "a"
# ⚠️左側の式が false の場合、右側が評価される
false || "a"
=> "a"
false || (1 + 2)
=> 3
code:.rb
m = true
m or n = true # m or (n = true)
n
=> nil
→変数未定義エラーにならない理由
n = true という代入式が一度書かれたことによりRubyはnをまだ代入されてないが、存在するローカル変数として認識し、値はnilに初期化される仕様になってる。
3つ
code: .rb
# 左から順に評価して最初にtrueとみなされる値を返す
false || 0 || "Hello"
=> 0
⚠️RExひっかけ問題
code:.rb
v1 = 1 - 1 == 0
v2 = v1 || raise RuntimeError
puts v2 && false
=> syntax error, unexpected constant, expecting `do' or '{' or '(' (SyntaxError)
エラーの理由
||の優先順位が高いため、v1 || raiseが評価されることになるが、後ろにRuntimeErrorがあるため、SyntaxErrorになる。
エラーにならない書き方
code:.rb
v2 = v1 or raise RuntimeError
v2 = v1 || raise(RuntimeError)
v2 = v1 || (raise RuntimeError)