Question

Disons que j'ai une classe 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

Si j'essaie de faire MyClass.property=x, la valeur de retour de la déclaration dans son ensemble est toujours x. Il est une convention dans beaucoup de langues C-base / inspiré pour retourner une valeur booléenne « succès » - est-il possible de le faire pour un poseur en utilisant la « syntaxe est égal à » Ruby

?

De plus - si cela est impossible, pourquoi pas? Y at-il concevable inconvénient de permettre une opération « égale setter » retourne une valeur?

Était-ce utile?

La solution

Un inconvénient est que vous briser la sémantique d'affectation enchaînées:

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

Considérez:

x = MyClass.property = 3

Alors x prendrait true si cela a fonctionné comme vous l'aviez prévu (droit associativité). Cela pourrait être une surprise pour les personnes utilisant l'interface et utilisée pour la sémantique typique.

Vous avez aussi m'a fait penser à l'affectation parallèle, par exemple:

x, y = 1, 2

Apparemment, la valeur de retour de cette expression est mise en œuvre spécifique ... Je suppose que je ne seront pas enchaînant des missions parallèles:)

Nice question!

Autres conseils

Comme le dit Martin, cela casserait Enchaînement d'affectation.

La façon dont les méthodes d'affectation rubis sont définis au travail se développe MyClass.property = 3 à l'équivalent de (lambda { |v| MyClass.send('property=', v); v })[3] (pas vraiment, mais cela montre comment enchaînant les travaux). La valeur de retour de la mission est toujours la valeur attribuée.

Si vous voulez voir le résultat de votre méthode de MyClass#property=, puis utilisez #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

Cependant, la manière rubis de le faire est avec des exceptions - en cas de problème au cours la mission, soulever une exception. Ensuite, tous les invocateurs doivent manipuler si quelque chose va mal, à la différence d'une valeur de retour, qui peut être facilement ignoré:

# 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

Je ne suis pas un expert Ruby mais je dirais que non pour ce cas, j'ai peur. Un poseur de propriété est uniquement là pour définir la valeur d'un champ privé, de ne pas avoir des effets secondaires tels que des codes de résultat retour.

Si vous voulez que la fonctionnalité puis oublier le poseur et d'écrire une nouvelle méthode appelée TrySetProperty ou quelque chose qui tente de définir la propriété et renvoie une valeur booléenne.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top