Ruby: динамически генерировать атрибут_accessor
Я пытаюсь создать attr_reader из хэша (с вложенным хешем), чтобы он автоматически копировал создание экземпляра_вариабеля.
вот что я до сих пор:
data = {:@datetime => '2011-11-23', :@duration => '90', :@class => {:@price => '£7', :@level => 'all'}}
class Event
#attr_reader :datetime, :duration, :class, :price, :level
def init(data, recursion)
data.each do |name, value|
if value.is_a? Hash
init(value, recursion+1)
else
instance_variable_set(name, value)
#bit missing: attr_accessor name.to_sym
end
end
end
Но я не могу найти способ сделать это: (
Ответы
Ответ 1
Вам нужно вызвать метод (private) класса attr_accessor
в классе Event
:
self.class.send(:attr_accessor, name)
Я рекомендую вам добавить @
в эту строку:
instance_variable_set("@#{name}", value)
И не используйте их в хеше.
data = {:datetime => '2011-11-23', :duration => '90', :class => {:price => '£7', :level => 'all'}}
Ответ 2
Вы можете немного метамагии решить эту проблему, используя метод_поиск:
class Event
def method_missing(method_name, *args, &block)
if instance_variable_names.include? "@#{method_name}"
instance_variable_get "@#{method_name}"
else
super
end
end
end
Что это будет делать, так это разрешить доступ к переменным экземпляра объекта через синтаксис object.variable, если объект имеет эти переменные, не прибегая к модификации всего класса через attr_accessor.
Ответ 3
attr_accessor
- метод класса и как таковой должен быть вызван в классе. Это также частный метод, поэтому вам нужно вызвать его в контексте, в котором объект класса self
.
В качестве примера:
class C
def foo
self.class.instance_eval do
attr_accessor :baz
end
end
end
После создания экземпляра C
и вызова foo
в этом экземпляре этот экземпляр - и все будущие экземпляры - будут содержать методы baz
и baz=
.