Почему я не могу использовать attr_accessor внутри инициализации? - PullRequest
13 голосов
/ 14 ноября 2009

Я пытаюсь сделать instance_eval, за которым следует attr_accessor внутри initialize, и я продолжаю получать это: Почему это не работает?

Код выглядит примерно так:

class MyClass
   def initialize(*args)
      instance_eval "attr_accessor :#{sym}"
   end
end

Ответы [ 3 ]

20 голосов
/ 14 ноября 2009

Вы не можете вызвать attr_accessor для экземпляра, потому что attr_accessor не определен как метод экземпляра MyClass. Он доступен только для модулей и классов. Я подозреваю, что вы хотите вызвать attr_accessor для метакласса экземпляра, например:

class MyClass
  def initialize(varname)
    class <<self
      self
    end.class_eval do
      attr_accessor varname
    end
  end
end

o1 = MyClass.new(:foo)
o2 = MyClass.new(:bar)
o1.foo = "foo" # works
o2.bar = "bar" # works
o2.foo = "baz" # does not work
5 голосов
/ 20 февраля 2013

У Роба д'Аписа есть почти . Вам просто нужно написать:

self.singleton_class.send(:attr_accessor, varname)

или

self.singleton_class.class_eval "attr_accessor :#{varname}"

или мой любимый вариант

self.singleton_class.class_exec do attr_accessor varname end

при условии, что значение varname является символом

5 голосов
/ 25 мая 2011

Более чистая реализация ( Примечание: это добавит средство доступа ко ВСЕМ экземплярам класса, а не только к одному экземпляру, см. Комментарии ниже ):

class MyClass
  def initialize(varname)
    self.class.send(:attr_accessor, varname)
  end
end
...