我使用以下代码将哈希集合转换为我的类上的方法(有点像活动记录)。我遇到的问题是我的二传手不能正常工作。我对Ruby仍然很陌生,并且相信我已经让自己扭转了一下。
class TheClass
def initialize
@properties = {"my hash"}
self.extend @properties.to_methods
end
end
class Hash
def to_methods
hash = self
Module.new do
hash.each_pair do |key, value|
define_method key do
value
end
define_method("#{key}=") do |val|
instance_variable_set("@#{key}", val)
end
end
end
end
end
创建了方法,我可以在课堂上阅读它们,但设置它们不起作用。
myClass = TheClass.new
item = myClass.property # will work.
myClass.property = item # this is what is currently not working.
答案 0 :(得分:6)
如果您的目标是设置动态属性,则可以使用OpenStruct。
require 'ostruct'
person = OpenStruct.new
person.name = "Jennifer Tilly"
person.age = 52
puts person.name
# => "Jennifer Tilly"
puts person.phone_number
# => nil
它甚至内置支持从哈希
创建它们hash = { :name => "Earth", :population => 6_902_312_042 }
planet = OpenStruct.new(hash)
答案 1 :(得分:4)
您的getter方法始终返回原始哈希值。设置实例变量不会改变它;你需要让getter引用实例变量。类似的东西:
hash.each_pair do |key, value|
define_method key do
instance_variable_get("@#{key}")
end
# ... define the setter as before
end
您还需要在开始时设置实例变量,例如放入
@properties.each_pair do |key,val|
instance_variable_set("@#{key}",val)
end
初始化方法中的。
注意:我不保证这是最好的方法;我不是Ruby专家。但它确实有效。
答案 2 :(得分:2)
它对我来说很好(当然,在修复了代码中明显的语法错误之后):
myClass.instance_variable_get(:@property) # => nil
myClass.property = 42
myClass.instance_variable_get(:@property) # => 42
请注意,在Ruby中,实例变量总是私有的,你永远不会为它们定义一个getter,所以你实际上不能从外部查看它们(除了通过反射),但这并不意味着你的代码没有工作,这只意味着你看不到它的作用。
答案 3 :(得分:0)
这基本上就是我对method_missing的建议。我对这两种方式都不熟悉,不知道为什么或为什么不使用它,这就是我上面提到的原因。基本上这将为您自动生成属性:
def method_missing sym, *args
name = sym.to_s
aname = name.sub("=","")
self.class.module_eval do
attr_accessor aname
end
send name, args.first unless aname == name
end