为什么我不能在初始化中使用attr_accessor?

时间:2009-11-14 17:43:01

标签: ruby metaprogramming eval

我正在尝试instance_eval后跟attr_accessor initialize内部class MyClass def initialize(*args) instance_eval "attr_accessor :#{sym}" end end ,我继续这样做:``initialize':未定义方法'attr_accessor'。为什么这不起作用?

代码看起来像这样:

{{1}}

3 个答案:

答案 0 :(得分:20)

您无法在实例上调用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

答案 1 :(得分:5)

更清洁的实现( NB:这会将访问者添加到该类的所有实例,而不仅仅是单个实例,请参阅下面的注释):

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

答案 2 :(得分:5)

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的值是符号