C'è un modo per impostare le proprietà a IronRuby simile a C # di inizializzazione degli oggetti di sintassi?
Domanda
Sto usando IronRuby a fare un po 'di scripting nella mia app.
Ho un sacco di comandi (oggetti CLR) ho bisogno di creare ed eseguire, ma la maggior parte dei comandi bisogno proprietà impostate su di loro e voglio evitare di dover assegnare il comando a una variabile solo così posso impostare le proprietà.
C'è un modo per farlo come l'oggetto C # initializer sintassi ?
Soluzione
Non c'è costruito in modo di impostare le proprietà quando si costruiscono gli oggetti CLR, in quanto non è una funzionalità di Rubino stessa. Tuttavia, anche se Python non supporta questa operazione, IronPython fa supporto per permettervi di nome parametri da fornire ai costruttori . Dal momento che Ruby non supporta parametri denominati, non volevamo far rispettare un modello parametro denominato, sia esso un Hash
come ultimo argomento, o di un blocco che viene instance_eval
'd contro l'oggetto la costruzione, o qualcosa che la gente altro venire con.
Detto questo, entrambe le strategie di attuazione inizializzatori di oggetti possono essere scritti in puro Rubino senza alcun supporto speciale nel IronRuby. Descriverò sia elencati sopra, ma sentitevi liberi di sperimentare se non sono esattamente la sintassi che stavi cercando.
Supponendo la seguente classe CLR (scritto in C #):
namespace TestLib {
public class TestObj1 {
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
}
Si poteva immaginare l'inizializzazione gli oggetti con un blocco passato al costruttore:
testobj = TestObj1.new do
self.prop1 = "Prop1 Value"
self.prop2 = "Prop2 Value"
end
Ed ecco come si potrebbe sovrascrivere il metodo TestObj1.new
al supporto che:
class TestObj1
def self.new(*args, &block)
obj = super(*args)
obj.instance_eval &block
obj
end
end
Dal momento che questo eval
s in realtà il blocco contro l'oggetto appena creato, è possibile eseguire qualsiasi codice Ruby all'interno del blocco. Questo modello è popolare per la creazione di DSL e le API più naturali in Ruby.
O, se si preferisce usare la sintassi clemente Hash
di Ruby in argomenti di metodo:
testobj = TestObj1.new :prop1 => "Prop1 value", :prop2 => "Prop2 value"
Allora questo è come si potrebbe sovrascrivere il metodo .new
:
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
L'opzione Hash
è sicuramente un po 'più complicato, ma un po' più performante (in quanto evita eval
) ed è un modello più comune in Ruby per esporre parametri con nome.