Domanda

Diciamo che ho una 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

Se provo a fare MyClass.property=x, il valore di ritorno di tutta l'istruzione è sempre x.Si tratta di una convenzione in un sacco di C/ispirazione lingue per restituire un booleano "successo" valore - è possibile fare questo per un setter utilizzando la "sintassi è uguale a" Ruby?

Inoltre - se questo non è possibile, perché no?C'è qualche lato negativo concepibile consentendo un "uguale setter" operazione restituisce un valore?

È stato utile?

Soluzione

Uno svantaggio è che si potrebbe rompere il incatenato assegnazione semantica:

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

Prendere in considerazione:

x = MyClass.property = 3

Quindi x vorresti prendere true se questo ha funzionato come previsto (destra-associatività).Che potrebbe essere una sorpresa per le persone che utilizzano l'interfaccia e utilizzato per la tipica semantica.

È inoltre mi ha fatto pensare parallelo di assegnazione, ad esempio:

x, y = 1, 2

A quanto pare il valore restituito dall'espressione che è implementazione di specifiche...Credo di non essere il concatenamento parallelo assegnazioni :)

Bella domanda!

Altri suggerimenti

Come afferma Martin, questo potrebbe rompere l'assegnazione di concatenamento.

Il modo in cui ruby i metodi di assegnazione sono definiti per il lavoro si espande MyClass.property = 3 per l'equivalente di (lambda { |v| MyClass.send('property=', v); v })[3] (non proprio, ma questo dimostra come il concatenamento di opere).Il valore di ritorno della cessione è sempre il valore assegnato.

Se volete vedere il risultato del tuo MyClass#property= il metodo, quindi utilizzare #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

Tuttavia, il rubino modo per farlo è con eccezioni - se qualcosa va storto durante l'assegnazione, sollevare un'eccezione.Quindi tutte armatura deve gestire, se qualcosa non va sbagliato, a differenza di un valore di ritorno, che può essere facilmente ignorato:

# 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

Io non sono un Rubino sono un esperto, ma direi di no per quel caso ho paura.Un setter è solo lì per impostare il valore di un campo privato, non ha effetti collaterali come tornare i codici di risultato.

Se si desidera che la funzionalità di dimenticare il setter e scrivere un nuovo metodo chiamato TrySetProperty o qualcosa che tenta di impostare la proprietà e restituisce un valore booleano.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top