Подтвердить что ты не робот

Почему я не могу использовать attr_accessor внутри инициализации?

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

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

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

Ответ 1

Вы не можете вызвать 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

Ответ 2

Чистая реализация (NB: это добавит аксессуар ко всем экземплярам класса, а не только к одному экземпляру, см. комментарии ниже):

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

Ответ 3

Rob d'Apice имеет право почти. Вам просто нужно написать:

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 является символом