看看这段代码:
class Person
attr_accessor :name, :age
def initialize(data)
data.each { |k, v| self.send("#{k}=", v) }
end
end
data = {
name: 'Luke Skywalker',
age: 19
}
person = Person.new(data)
person.inspect # => #<Person @name="Luke Skywalker", @age=19>
这很好。它完成了它应该做的事情。问题是,我不希望属性是可变的,换句话说,我想使用attr_reader
。我知道,如果我使用attr_reader
,Ruby将不会为我(def attr=(val) ...
)创建writer方法,因此我将无法在"#{k}="
中使用send
。我真的不想这样做:
class Person
attr_reader :name, :age
def initialize(name:, age:)
@name = name
@age = age
end
end
你们知道实现我想要的解决方法吗?
感谢所有帮助!
答案 0 :(得分:1)
您可以使用instance_variable_set
,而不必依赖attr writer:
def initialize(data)
data.each { |key, value| instance_variable_set("@#{key}", value) }
end