Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Ruby: unless式にはelsifを書けない

やむを得ずif !hoge?で緊急避難的に切り抜けたそうです。

早速出たばかりのRuby 2.6.0で試しました。なお、私のpryのプロンプトはカスタマイズして短くしてあります。

» if true
»   puts 'hoge'
» elsif false
»   puts 'not hoge'
» end
hoge
» unless true
»   puts 'hoge'
» elsif true
SyntaxError: unexpected elsif, expecting end
elsif true
^~~~~

たしかにunlessブロックでelsifを使った時点でSyntaxErrorになりました。

何はともあれ、公式情報を見てみます。

参考: 制御構造 (Ruby 2.5.0)

unlessifと反対で、条件式が偽の時にthen以下の式を評価します。unless式にelsifを指定することはできません。
docs.ruby-lang.orgより

はみだしつっつき

「ちなみにunlesselsifは使えないけど、elseは使える😎」「あーそうだった」

» unless true
»   "not true"
» else
»   "true"
» end
#» "true"

「でもunlesselsifが使えないようになってるのは何となくワカル: そもそもunlessで使うelsifの挙動がわかりにくいし、それを許すと今度はelseunlessみたいなのも欲しいとかなってどんどんカオスになりかねないし」「たとえ仕様でelsifの挙動を定めたとしても、字面で混乱呼びそうですね😱」

「推測だけど、unlesselsifを許さないようになっているのは、言語設計者の意図なんじゃないかなー🤔」「私もそんな気がします」

「以下の関連記事にもありますけど、unlessってよっぽど条件がシンプルでelseも要らなくて、かつifよりunlessの方が読みやすい場合ぐらいにしか使わない方がよさそう: ガード構文とか」「でもガード構文でunless使うのはそれはそれでアンチパターン↓」「あ、そうか」「個人的にはunlessがそもそもアンチパターンぐらいに思ってるし」

def foo(a)
  return unless a.innocent? # unlessガードはよろしくない
  # 何かする
end

「ガード構文でunless使うぐらいなら、条件判定用のメソッドを1つ追加して、それをガードのifの条件に置く方がRubyらしく書けるし↓」「確かに、ifのガードに!を持ち込むよりずっと素直で読みやすいですね😋」

def foo(a)
  return if a.evil?
  # 何かする
end

...

def evil?
  !self.innocent?
end

おたより発掘

関連記事

Rubyにおけるunlessとコードの読みやすさについて

[Ruby/Rails] 例外で深くなったネストをGuard Clauseですっきりさせる


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。