2016-03-03 2 views
0

Привет Я хотел бы инициализировать атрибуты экземпляра объекта рубинового динамически через какой-то конфигурационный файл, я могу сделать это довольно быстро, используя следующий код:attr_accessor и мета-программирование в 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?

+2

Вы знаете, что делает 'attr_accessor', правильно? Таким образом, вы можете просто определить эти методы аналогичным образом с этой переменной экземпляра. –

+0

Вероятно, вы должны определить геттеры и сеттеры в * singleton class * вашего экземпляра. В противном случае вы будете загрязнять ваш класс ApiTester и, следовательно, каждый экземпляр. Другой вариант - генерировать весь класс динамически, на основе конфигурации. – Stefan

ответ

3
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, если вы можете.

Смежные вопросы