使用attr_reader发送对象#

时间:2019-01-17 06:37:03

标签: ruby

看看这段代码:

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

你们知道实现我想要的解决方法吗?

感谢所有帮助!

1 个答案:

答案 0 :(得分:1)

您可以使用instance_variable_set,而不必依赖attr writer:

def initialize(data)
  data.each { |key, value| instance_variable_set("@#{key}", value) }
end