Deklarieren von Instanzvariablen über eine Hash-Iteration!
-
06-07-2019 - |
Frage
Ich möchte folgendes tun:
Ich möchte die Instanzvariablen einer Klasse Iterieren über ein Wörterbuch erklären.
Nehmen wir an, dass ich diesen Hash haben
hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}
, und ich will jede Taste Instanzvariable einer Klasse haben. Ich möchte wissen, ob ich die Variablen über diese Hash-Iteration erklären könnte. So etwas wie folgt aus:
class MyClass
def initialize()
hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}
hash.each do |k,v|
@k = v
end
end
end
Ich weiß, das funktioniert nicht! ich diese nur von Code setzen Stück zu sehen, ob man konnte verstehen, was ich noch deutlicher werden soll.
Danke!
Lösung
class MyClass
def initialize()
hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}
hash.each do |k,v|
instance_variable_set("@#{k}",v)
# if you want accessors:
eigenclass = class<<self; self; end
eigenclass.class_eval do
attr_accessor k
end
end
end
end
Die Eigenklasse ein Sonderklasse Gehören nur auf ein einzelnes Objekt, so definierten Methoden geben Instanzmethoden des Objekts sein, aber gehören nicht zu anderen Instanzen des normalen Klasse des Objekts.
Andere Tipps
class MyClass
def initialize
# define a hash and then
hash.each do |k,v|
# attr_accessor k # optional
instance_variable_set(:"@#{k}", v)
end
end
end
Chuck Antwort ist besser als meine letzten zwei Versuche. Die Eigenklasse ist nicht self.class
wie ich gedacht hatte; es dauerte einen besseren Test als ich dies zu realisieren geschrieben hatte.
meinen alten Code verwendet, testete ich in der folgenden Art und Weise und stellte fest, dass die Klasse tatsächlich manipuliert wurde und nicht die Instanz:
a = MyClass.new :my_attr => 3
b = MyClass.new :my_other_attr => 4
puts "Common methods between a & b:"
c = (a.public_methods | b.public_methods).select { |v| a.respond_to?(v) && b.respond_to?(v) && !Object.respond_to?(v) }
c.each { |v| puts " #{v}" }
Der Ausgang war:
Common methods between a & b:
my_other_attr=
my_attr
my_attr=
my_other_attr
Das widerlegt eindeutig meine Voraussetzung. Ich entschuldige mich Chuck, Sie waren die ganze Zeit Recht.
ältere Antwort:
attr_accessor
funktioniert nur, wenn in einer Klassendefinition ausgewertet, nicht die Initialisierung einer Instanz. Deshalb wollen die einzige Methode, um direkt zu tun, was Sie ist instance_eval
mit einem String zu verwenden:
class MyClass
def initialize(params)
#hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}
params.each do |k,v|
instance_variable_set("@#{k}", v)
instance_eval %{
def #{k}
instance_variable_get("@#{k}")
end
def #{k}= (new_val)
instance_variable_set("@#{k}", new_val)
end
}
end
end
end
Mit diesem Versuch testen:
c = MyClass.new :my_var => 1
puts c.my_var
http://facets.rubyforge.org/apidoc/api /more/classes/OpenStructable.html
OpensStructable ist ein mixin Modul was kann OpenStruct Verhalten liefern zu jeder Klasse oder Objekt. OpenStructable ermöglicht Erweiterung von Datenobjekten mit beliebige Attribute.