attr_accessor и метапрограммирование в Ruby

Привет, я хотел бы динамически инициализировать атрибуты экземпляра объекта ruby ​​​​через некоторый файл конфигурации, я могу сделать это довольно быстро, используя следующий код:

class ApiTester

  def initialize(path= "api_test")
    h = eval(File.open("#{path}/config.hash","r").read)
    h.each do |k,v|
      eval("@#{k}=#{v.class == String ? "\"#{v}\"" :  v }" )
    end
  end

end

Как присвоить атрибуту "@#{k}" свойство attr_accessor?


person user1581422    schedule 03.03.2016    source источник
comment
Вы знаете, что делает attr_accessor, верно? Таким образом, вы можете просто определить эти методы аналогичным образом с этой переменной экземпляра.   -  person Sergio Tulentsev    schedule 03.03.2016
comment
Вам, вероятно, следует определить геттеры и сеттеры в одноэлементном классе вашего экземпляра. В противном случае вы загрязните свой класс ApiTester и, следовательно, каждый экземпляр. Другой вариант — динамически генерировать весь класс на основе конфигурации.   -  person Stefan    schedule 03.03.2016


Ответы (1)


class ApiTester
  def initialize(path= "api_test")
    h = { a: 1, b: 2 }
    h.each do |k,v|
      instance_variable_set("@#{k}", v)
      self.class.send(:attr_accessor, k)
    end
  end
end

api_tester = ApiTester.new
puts api_tester.a # => 1
puts api_tester.b # => 2

api_tester.a = 3
puts api_tester.a # => 3

Кстати, вам, вероятно, следует создать файл .yaml и использовать YAML::load_file, по возможности лучше избегать eval.

person Leventix    schedule 03.03.2016