声明实例变量迭代哈希!

我想做以下事情:

我想声明迭代字典的类的实例变量。

我们假设我有这个哈希值

hash = {"key1" => "value1","key2" => "value2","key3" => "value3"} 

我希望将每个键作为类的实例变量。 我想知道我是否可以声明迭代遍历该哈希的变量。 像这样的东西:

 class MyClass def initialize() hash = {"key1" => "value1","key2" => "value2","key3" => "value3"} hash.each do |k,v| @k = v end end end 

我知道这不起作用! 我只把这段代码放在一边看看你是否能理解我想要的更清楚。

谢谢!

 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< 

本征类是一个只属于单个对象的特殊类,因此在那里定义的方法将是该对象的实例方法,但不属于该对象的普通类的其他实例。

 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 

查克的回答比我最近的两次尝试要好。 本征类不像我想象的那样是自我类; 它花了一个比我写的更好的测试来实现这一点。

使用我的旧代码,我按以下方式测试,发现该类确实被操作,而不是实例:

 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}" } 

输出是:

 Common methods between a & b: my_other_attr= my_attr my_attr= my_other_attr 

这显然反驳了我的预设。 我很抱歉Chuck,你一直都是对的。

老答案:

attr_accessor仅在类定义中计算时才起作用,而不是在实例的初始化中起作用。 因此,直接执行所需操作的唯一方法是将instance_eval与字符串一起使用:

 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 

要测试此尝试:

 c = MyClass.new :my_var => 1 puts c.my_var 

http://facets.rubyforge.org/apidoc/api/more/classes/OpenStructable.html

OpensStructable是一个mixin模块,可以为任何类或对象提供OpenStruct行为。 OpenStructable允许使用任意属性扩展数据对象。