代码之家  ›  专栏  ›  技术社区  ›  Geo

为什么不能在初始化中使用attr_访问器?

  •  13
  • Geo  · 技术社区  · 15 年前

    我想做一个 instance_eval 其次是 attr_accessor 里面 initialize ,我一直得到这个:“initialize”:未定义的方法“attr_accessor”。为什么这个不起作用?

    代码看起来是这样的:

    class MyClass
       def initialize(*args)
          instance_eval "attr_accessor :#{sym}"
       end
    end
    
    3 回复  |  直到 12 年前
        1
  •  20
  •   sepp2k    15 年前

    不能在实例上调用attr_访问器,因为attr_访问器未定义为MyClass的实例方法。它只在模块和类上可用。我怀疑您想对实例的元类调用attr_访问器,如下所示:

    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
  •  5
  •   tokland    13 年前

    更清洁的实施( 注意:这将向类的所有实例添加访问器,而不仅仅是单个实例,请参见下面的注释。 ):

    class MyClass
      def initialize(varname)
        self.class.send(:attr_accessor, varname)
      end
    end
    
        3
  •  5
  •   semiomant    12 年前

    Rob d'apie有 几乎 正确的。你只需要写:

    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 是一个符号