¿Hay alguna manera de establecer propiedades en Ironruby similar a la sintaxis de inicializador de objeto C#?

StackOverflow https://stackoverflow.com/questions/9304459

  •  25-10-2019
  •  | 
  •  

Pregunta

Estoy usando Ironruby para hacer algunos secuencias de comandos en mi aplicación.

Tengo muchos comandos (objetos CLR) que necesito crear y ejecutar, pero la mayoría de los comandos necesitan propiedades establecidas en ellos y quiero evitar tener que asignar el comando a una variable solo para poder establecer las propiedades.

¿Hay alguna forma de hacerlo como el objeto C#? Sintaxis inicializadora?

¿Fue útil?

Solución

No existe una forma incorporada de configurar propiedades al construir objetos CLR, ya que no es una característica de Ruby. Sin embargo, aunque Python tampoco es compatible con esto, IronPython lo admite permitiendo que los parámetros nombrados se suministren a los constructores. Dado que Ruby no admite parámetros con nombre, no queríamos hacer cumplir un patrón de parámetros con nombre, ya sea un Hash como el último argumento, o un bloque que es instance_eval'D contra el objeto de construcción, o algo más que la gente se ocurra.

Dicho esto, ambas estrategias de implementación de inicializadores de objetos se pueden escribir en Ruby puro sin ningún apoyo especial en Ironruby. Describiré ambos mencionados anteriormente, pero no dude en experimentar si no son exactamente la sintaxis que estaba buscando.

Suponiendo la siguiente clase CLR (escrita en C#):

namespace TestLib {
  public class TestObj1 {
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
  }
}

Puede imaginar las propiedades de inicialización con un bloque pasado al constructor:

testobj = TestObj1.new do
  self.prop1 = "Prop1 Value"
  self.prop2 = "Prop2 Value"
end

Y así es como podrías anular el TestObj1.new Método para admitir eso:

class TestObj1
  def self.new(*args, &block)
    obj = super(*args)
    obj.instance_eval &block
    obj
  end
end

Dado que esto en realidad evalS El bloque contra el objeto recién creado, puede ejecutar cualquier código Ruby dentro del bloque. Este patrón es popular al crear DSL y más API naturales en Ruby.

O, si prefiere usar Ruby's Lenient Hash Sintaxis en argumentos de método:

testobj = TestObj1.new :prop1 => "Prop1 value", :prop2 => "Prop2 value"

Entonces así es como podrías anular el .new método:

class TestObj1
  def self.new(*args)
    last_arg = args[-1]
    if last_arg.kind_of?(Hash)
      first_args = args[0..-2]
      obj = super(*first_args)
      last_arg.each do |prop, val|
        obj.send("#{prop}=", val)
      end
      return obj
    end
    super(*args)
  end
end

los Hash La opción es definitivamente un poco más complicada, pero un poco más desempeñada (como evita eval) y es un patrón más común en Ruby para exponer los parámetros nombrados.

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