web-dev-qa-db-ja.com

Ruby:if variable vs if variable.nil?

Rubyは初めてですが、nilやfalseを除いてすべてのオブジェクトがtrueであることがわかりました。0でもtrueです。

言語のそのプロパティの良いところは、あなたが書くことができるということです:

if !variable
  # do stuff when variable is nil
end

より熟練した同僚Ruby開発者は、.nilを使用する代わりに、次のように選択するべきだと主張します:

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

ただし、後者の方が2つの理由でより良いオプションであると思います。1。特にRubyのような言語では、すべてがオブジェクトとメッセージの交換である。)では、よりオブジェクト指向であると思います。私の主題の意見では、コンパクトではありませんが、より読みやすくなっています。

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

11
Javier Holguera

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

別のテストを受けましょう。 .vowel?

if char == 'a'
   # do stuff
end

if char.vowel?
   # do stuff
end

さて、これらが同じことをしないことは明らかです。ただし、charaまたはbであると想定している場合は、機能します。しかし、次の開発者を混乱させます-2番目のブロックは、charが[eiou]である条件にも入るでしょう。ただし、aの場合、正しく動作します。

はい、それはnilfalseがRubyで唯一の偽の値である場合です。ただし、nil || falseをテストしてnilをテストしている場合、これはあなたが意図していることではありません。

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

exactlyを伝えるコードを記述します。

17
user40980

以下を検討してください。

_response = responses.to_a.first_

これは、responsesまたはnilの最初の要素を返します。次に、条件ステートメントはnilfalseとして扱うため、次のように記述できます。

_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の有用な側面です。

3
zetetic

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

2
Greg Burghardt

慣用的に、unless variableif !variableよりも望ましいです。否定されたifステートメントは、スキミング時に否定を見逃しやすいため、コードのにおいと見なされることがよくあります。

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

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

0
Matt Gibson