【发布时间】:2011-03-16 10:51:56
【问题描述】:
我正在尝试编写一个 Ruby 类,它在处理属性的方式上与 Rails AactiveRecord 模型类似:
class Person
attr_accessor :name, :age
# init with Person.new(:name => 'John', :age => 30)
def initialize(attributes={})
attributes.each { |key, val| send("#{key}=", val) if respond_to?("#{key}=") }
@attributes = attributes
end
# read attributes
def attributes
@attributes
end
# update attributes
def attributes=(attributes)
attributes.each do |key, val|
if respond_to?("#{key}=")
send("#{key}=", val)
@attributes[key] = name
end
end
end
end
我的意思是,当我初始化类时,“属性”散列会使用相关属性进行更新:
>>> p = Person.new(:name => 'John', :age => 30)
>>> p.attributes
=> {:age=>30, :name=>"John"}
>>> p.attributes = { :name => 'charles' }
>>> p.attributes
=> {:age=>30, :name=>"charles"}
到目前为止一切顺利。我想要发生的是在我设置单个属性时更新属性哈希:
>>> p.attributes
=> {:age=>30, :name=>"John"}
>>> p.name
=> "John"
>>> p.name = 'charles' # <--- update an individual property
=> "charles"
>>> p.attributes
=> {:age=>30, :name=>"John"} # <--- should be {:age=>30, :name=>"charles"}
我可以通过为每个属性编写一个 setter 和 getter 而不是使用attr_accessor 来做到这一点,但这对于一个有很多字段的模型来说会很糟糕。有什么快速的方法可以做到这一点?
【问题讨论】:
-
在您的
initialize方法中,您不需要使用send设置属性。只需更新@attributes哈希即可。attributes=方法也是如此。 -
我觉得这很常见,有人可以把它变成一个简单的宝石。
标签: ruby metaprogramming abstract-class class-attributes