Powiedzmy, że mam następujący hash:
{ :foo => 'bar', :baz => 'qux' }
Jak mogę dynamicznie ustawić klucze i wartości, aby stały się zmiennymi instancji w obiekcie ...
class Example
def initialize( hash )
... magic happens here...
end
end
... tak żebym miał w modelu następujące elementy ...
@foo = 'bar'
@baz = 'qux'
?
ruby
metaprogramming
instance-variables
Andrzej
źródło
źródło
hash.each {|k,v| instance_variable_set("@#{k}",v)}
hash.each &method(:instance_variable_set)
sposób metodainstance_variable_set
otrzymuje dwa parametry, których potrzebuje?h = { :foo => 'bar', :baz => 'qux' } o = Struct.new(*h.keys).new(*h.values) o.baz => "qux" o.foo => "bar"
źródło
.new()
robi drugi łańcuch ?Struct.new
tworzy nową klasę w oparciu o klucze mieszające, a następnie druganew
tworzy pierwszy obiekt właśnie utworzonej klasy, inicjując ją do wartości Hash. Zobacz ruby-doc.org/core-1.8.7/classes/Struct.htmlrequire 'ostruct'; h = {:foo => 'foo'}; o = OpenStruct.new(h); o.foo == 'foo'
Struct.new(*hash.keys.map { |str| str.to_sym }).new(*hash.values)
Sprawiasz, że chcemy płakać :)
W każdym razie zobacz
Object#instance_variable_get
iObject#instance_variable_set
.Miłego kodowania.
źródło
set_entity
wywołanie zwrotne dla wszystkich kontrolerów i nie chcę ingerować w istniejące zmienne instancjidef set_entity(name, model); instance_variable_set(name, model.find_by(params[:id])); end;
Możesz także użyć,
send
który zapobiega ustawianiu przez użytkownika nieistniejących zmiennych instancji:def initialize(hash) hash.each { |key, value| send("#{key}=", value) } end
Użyj,
send
gdy w twojej klasie jest seter, taki jakattr_accessor
dla zmiennych instancji:class Example attr_accessor :foo, :baz def initialize(hash) hash.each { |key, value| send("#{key}=", value) } end end
źródło