Pregunta

Digamos que tengo una clase 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 lo intento y hago MyClass.property=x, el valor de retorno de toda la declaración es siempre x. Es una convención en un montón de idiomas / inspirados para devolver un valor booleano "éxito" C-basada - es posible hacer esto por un colocador utilizando el "iguales sintaxis" en Ruby

?

Por otra parte - si esto no es posible, ¿por qué no? ¿Hay alguna desventaja concebible que permite un "colocador es igual a" operación devuelve un valor?

¿Fue útil?

Solución

Una desventaja es que usted se rompería la semántica de asignación encadenados:

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

Considere lo siguiente:

x = MyClass.property = 3

A continuación, x tomaría true si esto funcionó como se había esperado (asociatividad por la derecha). Eso podría ser una sorpresa para la gente que usa la interfaz y se utiliza para la semántica típicos.

También me hizo pensar en la asignación en paralelo, por ejemplo:

x, y = 1, 2

Al parecer, el valor de retorno de esa expresión es aplicación específica ... supongo que no será encadenar tareas paralelas:)

Niza pregunta!

Otros consejos

Al igual que Martin dice, esto rompería el encadenamiento de asignación.

La forma en los métodos de asignación de rubí se definen a trabajar expande MyClass.property = 3 al equivalente de (lambda { |v| MyClass.send('property=', v); v })[3] (no realmente, pero esto demuestra cómo funciona la cadena). El valor de retorno de la asignación es siempre el valor asignado.

Si desea ver el resultado de su método de MyClass#property=, a continuación, utilizar #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

Sin embargo, la forma de rubí de hacerlo es con excepciones - si algo va mal durante la asignación, provoca una excepción. A continuación, todos los invocadores deben manejar la situación si algo sale mal, a diferencia de un valor de retorno, que puede ser fácilmente ignorado:

# 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

No soy un experto en Rubí pero yo diría que no para ese caso me temo. Un colocador propiedad es el único allí para establecer el valor de un campo privado, no tiene efectos secundarios como devolver los códigos de resultado.

Si desea que la funcionalidad luego olvidarse la incubadora y escribir un nuevo método llamado TrySetProperty o algo que trata de establecer la propiedad y devuelve un valor lógico.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top