Ruby:if variable vs if variable.nil?


11

私はRubyを初めて使い、nilとfalseを除いてすべてのオブジェクトがtrueであることを知って驚いた。0でも真です。

言語のその特性についての良いところは、あなたが書くことができるということです:

if !variable
  # do stuff when variable is nil
end

経験豊富なRuby開発者である同僚は、.nilを使用する代わりにそれを選択すべきだと主張しています。そのようです:

if variable.nil?
  # do stuff when variable is nil
end

ただし、後者は次の2つの理由により優れたオプションであると考えています。2.私の主題の意見では、たとえそれがよりコンパクトでなくても、より読みやすいです。

ここで「初心者」の間違いを犯していますか?


4
nilをテストしていますか?または偽の値?

私はnilをテストしています。基本的に変数がnilの場合、私は何かをする(またはしない)
ハビエルホルゲラ

3
nilをテストしている場合、なぜfalseのテストもそのブロックに入るようにしたいのですか?

同意して、.nilを好むもう1つの理由としてそれを指摘しましたか?しかし、彼らはあなたがその変数がブール値ではありません知っているとき、「やる変数ならば、xが」より慣用的であり、好ましい「?variable.nilもしXやる」と主張した
ハビエルHolguera

回答:


17

あなたが意味することを書いてください。あなたが書いたものを意味します。

別のテストをしてみましょう。 .vowel?

if char == 'a'
   # do stuff
end

if char.vowel?
   # do stuff
end

さて、これらが同じことをしないことは明らかです。しかし、あなたがそうすることだけを期待しcharている場合、aまたはbそれが機能する場合。しかし、それは次の開発者を混乱させます-charがある条件のために2番目のブロックに入り[eiou]ます。ただし、aでは、正常に機能します。

はい、それはというケースであるnilfalseRubyで唯一falsy値です。ただし、をテストすることでをテストしnilている場合nil || false、これはあなたが言うことではありません。

それは次の開発者(たまたまあなたの自宅の住所を知っている狂ったa殺人者)がコードを読み、なぜfalseそこにも入るべきなのか疑問に思うことを意味します。

正確にあなたが意味することを伝えるコードを書いてください。


3

以下を考慮してください。

response = responses.to_a.first

これはresponses、またはの最初の要素を返しnilます。そして、条件文を扱うためnilとしてfalse、我々は書くことができます。

response = responses.to_a.first
if response
  # do something ('happy path')
else
  # do something else
end

どちらがより読みやすいですか:

if response.nil?
  # do something else
else
  # do something ('happy path')
end

if (object)パターンは、Rubyのコードでは非常に一般的です。また、次のようにリファクタリングにうまくつながります:

if response = responses.to_a.first
  do_something_with(response)
else
  # response is equal to nil
end

また、Rubyメソッドはnilデフォルトで返されることも覚えておいてください。そう:

def initial_response
  if @condition
    @responses.to_a.first
  else
    nil
  end
end

次のように簡略化できます。

def initial_response
  if @condition
    @responses.to_a.first
  end
end

したがって、さらにリファクタリングできます。

if response = initial_response
  do_something_with(response)
else
  # response is equal to nil
end

帰国nilは必ずしも最良のアイデアとは限らない、と主張することができますnil。なぜなら、それはあらゆる場所をチェックすることを意味するからです。しかし、それは別の魚のやかんです。オブジェクトの「存在または不在」のテストが頻繁に要求されることを考えると、オブジェクトの真実性はRubyの有用な側面ですが、この言語の初心者にとっては驚くべきことです。


2

Rubyは緩やかに型付けされた言語であるためif variable.nil?、自然言語のように読まれるだけでなく、プログラマーが誤ってfalse値を割り当ててifステートメントに陥るのを防ぎます。


1
それで、元の質問の最初のコメントは間違っていましたか?「変数がnilまたはfalseの場合に処理を行う」べきでしたか?そして、コメントに一致しないコードはバグなので、すぐにバグがありますか?
gnasher729

正しい。単純な真実性テストでは、論理エラーが発生する可能性があります。
グレッグブルクハート

0

慣用的に、unless variableが望ましいif !variable。否定if文は、スキミング時に否定を見逃しやすいため、多くの場合、コードのにおいと見なされます。

ここでの全体像は、nilこのようなチェックを行うことも少しコード臭いことです。適切なオブジェクト指向のために、nullオブジェクトパターンを使用して、この種のチェックが不要になるようにします。http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness/

オブジェクトに何をすべきかを伝え、何であるかを尋ねないでください。これは、「尋ねないでください」と呼ばれることもあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.