12

Rubyクラスがあるとしましょう:

class MyClass
  def self.property
    return "someVal"
  end

  def self.property=(newVal)
    # do something to set "property"
    success = true

    return success # success is a boolean
  end
end

試してみるとMyClass.property=x、ステートメント全体の戻り値は常に x になります。ブール値の「成功」値を返すことは、多くの C ベース/インスパイアされた言語の規則です。Ruby で「equals 構文」を使用してセッターに対してこれを行うことは可能ですか?

さらに、これが不可能な場合、それはなぜですか? 「等号セッター」操作が値を返すことを許可することの考えられる欠点はありますか?

4

3 に答える 3

11

1つの欠点は、連鎖割り当てのセマンティクスを破ることです。

$ irb 
irb(main):001:0> x = y = 3
=> 3
irb(main):002:0> p x
3
=> nil
irb(main):003:0> p y
3
=> nil
irb(main):004:0> 

検討:

x = MyClass.property = 3

次に、これが期待どおりに機能したかどうかを確認します(右結合性)xtrueこれは、インターフェースを使用し、典型的なセマンティクスに慣れている人々にとっては驚きかもしれません。

また、並列割り当てについて考えさせられました。例:

x, y = 1, 2

どうやらその式からの戻り値は実装固有です...私は並列割り当てを連鎖させないと思います:)

いい質問です!

于 2009-04-02T08:14:22.383 に答える
7

マーティンが言うように、これは割り当ての連鎖を壊します。

ルビー代入メソッドが機能するように定義される方法はMyClass.property = 3、同等のものに拡張され(lambda { |v| MyClass.send('property=', v); v })[3]ます(実際にはそうではありませんが、これは連鎖がどのように機能するかを示しています)。割り当ての戻り値は、常に割り当てられた値です。

MyClass#property=メソッドの結果を確認したい場合は、以下を使用して#sendください。

irb> o = Object.new
=> #<Object:0x15270>
irb> def o.x=(y)
irb>   @x = y+1
irb>   puts "y = #{y}, @x = #@x"
irb>   true
irb> end
=> nil
irb> def o.x
irb>   puts "@x = #@x"
irb>   @x
irb> end
=> nil
irb> o.x = 4
y = 4, @x = 5
=> 4
irb> o.x
@x = 5
=> 5
irb> o.send('x=', 3)
y = 3, @x = 4
=> true

ただし、これを行うためのルビーの方法は例外です。割り当て中に問題が発生した場合は、例外を発生させます。次に、簡単に無視できる戻り値とは異なり、何か問題が発生した場合は、すべての呼び出し元がそれを処理する必要があります。

# continued from above...
irb> def o.x=(y)
irb>   unless y.respond_to? :> and (y > 0 rescue false)
irb>     raise ArgumentError, 'new value must be > 0', caller
irb>   end
irb>   @x = y + 1
irb>   puts "y = #{y}, @x = #@x"
irb> end
=> nil
irb> o.x = 4
y = 4, @x = 5
=> 4
irb> o.x = 0
ArgumentError: new value must be > 0
    from (irb):12
    from :0
irb> o.x = "3"
ArgumentError: new value must be > 0
    from (irb):13
    from :0
irb> o.x
@x = 5
=> 5
于 2009-04-02T12:12:07.273 に答える
5

私は Ruby の専門家ではありませんが、残念ながらその場合はノーと言いたいです。プロパティ セッターは、プライベート フィールドの値を設定するためだけに存在し、結果コードを返すような副作用はありません。

その機能が必要な場合は、セッターを忘れて、呼び出された新しいメソッドTrySetPropertyまたはプロパティを設定しようとしてブール値を返す何かを記述します。

于 2009-04-02T07:19:08.757 に答える