我找到了这个有趣的答案:
https://stackoverflow.com/a/2348854/169277
当您尝试设置实例变量时,这很好。
有没有办法应用相同的逻辑或更好的逻辑来创建通用构造函数,如:
def initialize(obj)
obj.each do |k,v|
#find the setter for each k and set the value v to and return newly created object
end
end
如果我有对象TestObject
:
class TestObject
attr_accessor :name, :surname, :sex
end
我正在考虑创建这样的东西:
TestObject.new({:name => 'Joe', :surname => 'Satriani'})
如何实现这一目标?
这样做可以简写:
t = TestObject.new
t.name = 'Joe'
t.surname = 'Satriani'
答案 0 :(得分:1)
当然,您可以使用send向对象发送任意消息。由于我们在此处self
进行操作,因此我们可以直接调用send
。
def initialize(obj)
obj.each do |k,v|
send(:"#{k}=", v)
end
end
例如,TestObject.new({:name => 'Joe'})
会调用send "name=", "Joe"
。
答案 1 :(得分:1)
您可以从Struct继承以创建一个简单对象,然后将属性传递给初始化程序:
class TestObject < Struct.new(:name, :surname, :sex)
end
TestObject.new('Joe', 'Satriani') #=> sex will be nil
您可以使用OpenStruct制作具有任意属性的快速值对象:
t = OpenStruct(name: 'Joe', surname: 'Satriani')
您可以添加像Virtus这样的模块:https://github.com/solnic/virtus
或者你可以做Chris Heald所说的。
答案 2 :(得分:0)
我认为最好使用关键字参数。毕竟,Hash
密钥保证是有效的Ruby标识符Symbol
,因为它们需要与方法名称匹配。您不需要将任意Ruby对象作为Hash
的键传递。
def initialize(**attrs)
attrs.each do |attr, value| send(:"#{attr}=", value) end
end
TestObject.new(name: 'Joe', surname: 'Satriani')