2009-06-04 6 views

答えて

33

あなたは条件付きの割り当てを探しています:

a ||= b # Assign if a isn't already set 

と||オペレータ

a = b || 2 # Assign if b is assigned, or assign 2 
+9

これは私の答えに概説された理由で、うまくいきません。最初の例ではaをfalseに、2番目の例ではbをfalseに設定してみてください。 –

+0

正解、@JörgWMittag。真実/虚偽のことに注意してください! –

+0

また、「?」で「nilに割り当てることはできません」というエラーは表示されません。しかし、オブジェクトの上にifNilメソッドを記述し、Smalltalkのようにブロックを評価するためにNilClassに書くことができます – Rivenfall

5
x = b || 2 

は、それ(C#で??)が合体演算子と呼ばれます。 Rubyで

+2

これは、私の答えで概説した理由のためにはうまくいかないでしょう。この例では、bをfalseに設定してみてください。 –

46

、短絡ブール演算子(||&&andor)はtrue又はfalseを返すのではなく、全体の発現の結果を決定する第1オペランドありません。これはうまくいく。なぜなら、Rubyは真実のほんの単純な考えを持っているからだ。または、むしろ、それは虚偽のむしろ単純な考えを持っています:nilは偽であり、明らかにfalseは偽です。 他のすべては真です。だから、

、そのオペランドの少なくとも1がtrueで、オペランドは、左から右に評価されたときに||が真であるためには、このことはa || b戻りaaが真です。しかし、aがfalseの場合、式の結果はbのみに依存するため、bが返されます。

これは、nilがfalseであるため、指定した例として??の代わりに||を使用することができます。 (また、気の利いたa ||= bオペレータ、a || a = bのような作品のようなものではなく、かなりあります。)しかし

のみの作品は、あなたがあなたの例でブール値を使用しないためという。あなたはブール値を扱うことが予想される場合は、動作しないこと:その場合は

b = false 

x = b || 2 # x should be == false, but will be 2 

を、あなたは#nil?を使用する必要がありますし、条件式:

b = false 

x = unless b.nil? then b else 2 end # x should be == 2 

または三条件を使用してオペレータ:

b = false 

x = b.nil? ? 2 : b # x should be == false 

あなたは、あなたが素敵な方法でそれを包むことができますしたい場合:

class Object 
    def _? b = nil 
    return self 
    end 
end 

class NilClass 
    def _? b = nil 
    return yield if block_given? 
    return b 
    end 
end 

b = false 

x = b._? { 2 } # x should be == false 
x = b._? 2 # x should be == false 

このかわいいスニペットは、多型、オープンクラスとnilが実際に(nullが実際何もありませんジャワ、たとえば、とは異なり、)虚無を表すオブジェクトであるという事実によってもたらさ。

+0

'a || = b'はそれほど多くの「種類」ではありません。 a = b'であるが、正確にはa = a || b。条件付き代入ではなく、代入が常に発生します。 – Theo

+5

@Theo:これは、現在のISO Ruby言語仕様の草案が言っていることですが、それは間違っています。 MRI、YARV、JRuby、Rubinius、XRuby、MacRuby、IronRuby、Ruby.NET、MagLev、SmallRuby、tinyrb、RubyGoLightlyなどこれまでに作成されたすべてのRuby実装は、短絡条件付き割り当てとして実装されています。 Rubyプログラミング言語(matz自身が共同で作ったもの)、Rubyをプログラミングすること、そしてこれまでに書かれたRubyのすべての本をそのように書いています。 RubySpecテストスイートはそれをテストします。 StackOverflowに関する数回の議論とルビートークに関する数十の議論がそう言います。 Matz自身がそう言います。 –

+0

ピーター・クーパーの記事への必須リンク: http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html –

1

coalesce宝石があります。これはあなたと同じくらい近いです。

nil || 5 # => 5 
false || 5 # => 5 :(
false._? 5 # => false :)