🐈

[Rails]そのunless、ifじゃダメですか?

2022/10/18に公開

お仕事で書いたコードのレビューで、先輩エンジニアさんから「ここのunlessifの方が良いです」という旨のコメントを頂きました。
私自身、いつからかifunlessで先に思いついた方を使うようになっていたので、自戒の意を込めて、また、私と同じ失敗をする人が出ないようにするために、本記事を残します。


unlessを使うようになった契機

本当にrailsに触り始めた頃、以下のようなコードを書きました。

if !hero.()
end

すると、rubocopくんが

unless hero.()
end

と書くように! と怒ってきたのです。
unlessを知らなかった当時の私は「unless便利やん」ぐらいに思ってしまいました。
それから私は、ifunlessをその場のノリで使い分けるようになっていきます。。。。

結論:unlessを使う前に一呼吸置いてほしい

簡単な例から

if !hero.blank?

を日本語訳すると、「もし、ヒーローが存在していないでないとき」となる。かなり不自然な日本語である。

一方で、

unless hero.blank?

を日本語訳すると、「もし、ヒーローが存在していないことはないとき」という、これまた不自然な日本語になる。(上よりはマシなので、rubocopくんが悪いとは思わないが)

if hero.present?

を日本語訳すると、「もし、ヒーローが存在するとき」という、自然かつ理解のしやすい日本語になる。

次に、少し複雑な例で考える

unless hero.age > villain.age

日本語訳すると、「ヒーローの年齢がヴィランの年齢より上で『ない』とき」

if hero.age <= villain.age

日本語訳すると、「もしヒーローの年齢がヴィランの年齢以下のとき」

否定が入らない分、後者の方が理解しやすい日本語となっているだろう。

もっと複雑な例で

unless hero.blank? || villain.blank?

自分で書いておいてなんだが、もはや理解不能である。
「ヒーローが存在していないか、もしくは、ヴィランが存在していない、ではないとき」っていつだよ。

というわけでif文にしましょう

if hero.present? && villain.present?

「ヒーローが存在していて、かつ、ヴィランが存在しているとき」と素直にわかります。

結論をもう一度:unlessを使う前に一呼吸置いて、日本語訳してみよう

可読性の高いコードの方が良いなんてことは周知の事実のはずだ。
であれば、自身の書いたコードを即座に日本語訳できるか、その日本語は理解しやすいものかを考えれば、それが良いコードか否かはわかるはずである
そこら辺をサボると私のように可読性の低いコードを書いてしまうので、皆さんには(特に私のような初心者には)注意していただきたい。

最後にもう一度、基本的にはifの方が理解しやすいです。
しかし、unlessの方が良い場合もあるので、日本語訳をしましょう
あなたが書いたコードを読むのはコンピュータと人間です。
コンピュータは少々汚いコードでも読んでくれます。
だから、人間に優しいコードを書きましょう。
というか、そういうコードを書くように心がけます(猛省)


参考文献
https://techracho.bpsinc.jp/hachi8833/2018_06_01/56980

Discussion