Rubyのif文ではelsifを使って複数の条件を書くことができます。
def greet_to(name)
if name == 'Alice'
puts 'Hi, Alice!'
elsif name == 'Bob'
puts 'Hi, Bob!'
end
end
greet_to('Alice')
#=> Hi, Alice!
greet_to('Bob')
#=> Hi, Bob!
それでは次のようにelsifの条件式を無くすとどうなるでしょうか?
def greet_to(name)
if name == 'Alice'
puts 'Hi, Alice!'
- elsif name == 'Bob'
+ elsif
puts 'Hi, Bob!'
end
end
答えはこうです。(あれ、さっきと同じ!?)
greet_to('Alice')
#=> Hi, Alice!
greet_to('Bob')
#=> Hi, Bob!
条件式なしのelsifはelsif true
と同じ意味になるんでしょうか?🤔
ためしに今度はifの条件式もなくしてみましょう。
def greet_to(name)
- if name == 'Alice'
+ if
puts 'Hi, Alice!'
elsif
puts 'Hi, Bob!'
end
end
これだと結果はどうなるんでしょうか?というか、そもそもこんなコード、動くんでしょうか?
greet_to('Alice')
#=> Hi, Alice!
# Hi, Bob!
greet_to('Bob')
#=> Hi, Alice!
# Hi, Bob!
動いた〜!けど、なんだこれ?AliceもBobも両方出力されてますね……。
種明かし
実はこれ、こう書いたのと同じ意味になっています。
def greet_to(name)
if puts 'Hi, Alice!'
# Do nothing
elsif puts 'Hi, Bob!'
# Do nothing
end
end
つまり、putsの呼び出しが条件式として扱われているわけですね。
で、putsの戻り値はnil
なのでputs 'Hi, Alice!'
は偽として扱われ、続いてelsifの条件式 puts 'Hi, Bob!'
が実行される、というわけです。
なので、たとえばputsの代わりにpメソッドを使うと結果が変わります。(pメソッド戻り値は引数として渡したオブジェクト自身になり、真と評価されるため)
def greet_to(name)
if
p 'Hi, Alice!'
elsif
p 'Hi, Bob!'
end
end
greet_to('Alice')
#=> "Hi, Alice!"
greet_to('Bob')
#=> "Hi, Alice!"
最初に見せたコードも条件式をわざと改行させるとこんなふうに書けます。(よい子はマネしちゃいけません)
def greet_to(name)
if
name == 'Alice'
puts 'Hi, Alice!'
elsif
name == 'Bob'
puts 'Hi, Bob!'
end
end
greet_to('Alice')
#=> Hi, Alice!
greet_to('Bob')
#=> Hi, Bob!
こんなコードをわざわざ書く人はいないでしょうし、書くべきでもないですが、if/elseと書くつもりがうっかりif/elsifと書いてしまうと、構文エラーにならない代わりに予期しない不具合を起こすかもしれないので気をつけましょう。
def greet_to(name)
if name == 'Alice'
puts 'Hi, Alice!'
elsif # ← 本当はelseと書くつもりが間違えた
puts 'Hi, Bob!'
end
end
なお、ifやelsifのうしろには条件式が必要なので、次のようなコードを書いたときは構文エラーになります。
def greet_to(name)
if name == 'Alice'
puts 'Hi, Alice!'
elsif
# elsifに対応する条件式がない(構文エラー)
end
end
#=> syntax error, unexpected `end'
# syntax error, unexpected end-of-input, expecting `end'
おまけ:case/whenだったら?
以下のようにcase/whenを使った条件分岐で、when 'Bob'
をwhen
だけにしてみるとどうなるでしょうか?
def greet_to(name)
case name
when 'Alice'
puts 'Hi, Alice!'
when
puts 'Hi, Bob!'
end
end
#=> syntax error, unexpected string literal, expecting `do' or '{' or '('
# puts 'Hi, Bob!'
むむむ、構文エラーが起きました。
が、次のように()
付きでputsを呼び出すとエラーになりません。
def greet_to(name)
case name
when 'Alice'
puts 'Hi, Alice!'
when
puts('Hi, Bob!')
end
end
greet_to('Alice')
#=> Hi, Alice!
greet_to('Bob')
#=> Hi, Bob!
とはいえ、これもif/elsifの場合と同じく、puts('Hi, Bob!')
がwhen節の条件式になっているだけです。
def greet_to(name)
case name
when 'Alice'
puts 'Hi, Alice!'
when puts('Hi, Bob!')
# (こう書いてるのと同じ)
end
end