0

我发现了这个有趣的答案:

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'
4

3 回答 3

1

当然,您可以使用send向对象发送任意消息。由于我们在self这里操作,我们可以直接调用send

def initialize(obj)
  obj.each do |k,v|
    send(:"#{k}=", v)
  end
end

例如,TestObject.new({:name => 'Joe'})将调用send "name=", "Joe".

于 2013-07-17T21:30:44.177 回答
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 所说的去做。

于 2013-07-17T21:32:30.090 回答
0

我认为最好为此使用关键字参数。毕竟,Hash键被保证是有效Symbol的 Ruby 标识符,因为它们需要与方法名称匹配。您不需要将任意 Ruby 对象作为Hash.

def initialize(**attrs)
  attrs.each do |attr, value| send(:"#{attr}=", value) end
end

TestObject.new(name: 'Joe', surname: 'Satriani')
于 2013-07-17T22:28:56.583 回答