Frage

Lassen Sie uns sagen, dass ich eine Ruby-Klasse haben:

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

Wenn ich versuche, und tun MyClass.property=x, der Rückgabewert der gesamten Aussage ist immer x. Es ist eine Konvention, in einer Menge von C-basierten / inspirierte Sprachen eines boolean „Erfolg“ Wert zurück - ist es möglich, dies für einen Setter zu tun mit der „gleich Syntax“ in Ruby

?

Außerdem - wenn dies nicht möglich ist, warum nicht? Gibt es einen denkbaren Nachteil so dass eine „gleich Setter“ Operation einen Wert zurückgeben?

War es hilfreich?

Lösung

Ein Nachteil ist, dass Sie die verkettete Zuweisung Semantik brechen würde:

$ 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> 

Bedenken Sie:

x = MyClass.property = 3

Dann würde x true wenn dies wie erwartet gearbeitet hatte (rechte Assoziativität). Das könnte eine Überraschung für Leute mit Ihrer Schnittstelle und die typischen Semantik verwendet.

Du hast auch denken, mich um parallele Zuordnung, zum Beispiel:

x, y = 1, 2

Anscheinend ist der Rückgabewert von diesem Ausdruck Implementierung spezifische ... Ich glaube, ich nicht parallel Zuweisungen werden Verkettungs:)

Nizza Frage!

Andere Tipps

Wie Martin sagt, dies würde Zuordnung Verkettungs brechen.

Die Art und Weise Rubin Zuordnungsverfahren zu arbeiten, sind definiert erweitert MyClass.property = 3 auf das Äquivalent von (lambda { |v| MyClass.send('property=', v); v })[3] (nicht wirklich, aber dies zeigt, wie Verkettungs Werke). Der Rückgabewert des Auftrags ist immer der Wert zugewiesen.

Wenn Sie das Ergebnis Ihrer MyClass#property= Methode sehen möchten, dann #send verwenden:

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

Allerdings ist der rubin Weg, dies zu tun ist, mit Ausnahmen - wenn etwas schief geht während Die Zuordnung, eine Ausnahme ausgelöst. Dann werden alle Aufrufer muss damit umgehen, wenn etwas geht falsch, im Gegensatz zu einem Rückgabewert, die leicht ignoriert werden können:

# 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

Ich bin kein Experte Rubin, aber ich würde sagen, nicht für den Fall, dass ich Angst habe. Eine Eigenschaft Setter ist es nur den Wert eines privaten Bereichs zu setzen, keine Nebenwirkungen zu haben, wie Ergebniscodes zurück.

Wenn Sie möchten, dass die Funktionalität dann die Setter vergessen und eine neue Methode namens TrySetProperty oder etwas zu schreiben, die die Eigenschaft zu setzen versucht und gibt einen boolean.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top