6

私が次のようなものを持っているとしましょう

true && true #=> true

これは理にかなっているので、次のようなことを試します。

true && "dsfdsf" #=> "dsfdsf"

if something && something多くの場合、私は次のようなことをしますが、それが true に評価されて true を返すといつも思っていたので、これは私を驚かせます。次のようなことを行うさらなる実験:

jruby-1.7.3 :009 > "ad" && "dsf"
 => "dsf" 
jruby-1.7.3 :010 > "ad" && "sdfd" && nil
 => nil 
jruby-1.7.3 :011 > "ad" && nil && "sdf"
 => nil 

Ruby は、すべてが true の場合は最後の値を返すか、最初に見つかった false の値を返すように見えます。なぜこれを行うのですか?これは正しいメンタルモデルですか?

4

2 に答える 2

10

ruby のブール演算子は短絡的です: 左辺の引数から式の値を決定できる場合、右辺の引数は評価されません。

したがって、ブール式を評価するためのより単純なメンタル モデルは、&&2 つのオペランドのみを含む最初の式を考慮することです。左側のオペランドが最初に評価されます。このオペランドの値がnilorfalseの場合、オペランドが返され、右側のオペランドは評価されません。左側のオペランドがそれ以外の場合、右側の演算子が評価され、その値が返されます。

trueこの定義から、お気づきのように、ブール演算子を含む式はorを返さずfalse、単にtrue 値またはfalse 値を返すことが明らかです。これは、ブール式がtrue-nessまたはfalse-nessのみに使用されるコンテキストでは何の違いもないことに注意してください。

ブール演算子は左結合であるため、複数の演算子を含む式の評価順序を簡単に決定できます。これは、&&よりも優先順位が高い||ことに注意してください (ただし、同じ優先順位andを持つことに注意してください)。orこれを行うと、式の値が最後に評価された要素、つまり式の全体的な真偽を判断できる要素であることが簡単わかります

あなたの例(&&演算子のみで構成される式)では、式の値は、最初のfalse 値が検出されるとすぐに、または最後の要素がtrue 値として評価された後にわかります。そのため、最後に評価された要素は、その前のすべての要素がtrue 値の場合は最後の要素になり、最初のfalse 値の要素が検出された場合はその要素になります。

なぜ式の値がtrueorに変換されないのか不思議に思うかもしれませんfalse。実際、この種の動作は次のようなイディオムで使用できます。

x = x || default

またはより短い

x ||= default

かどうかを確認するために使用され、その場合xnilデフォルト値を割り当てます。

于 2014-03-28T15:30:46.840 に答える