将值传递给使用Class.new创建的类

时间:2012-11-23 13:03:33

标签: ruby metaprogramming

我有一个名单和值列表,我正在尝试阅读并转换为类,因此我使用的是Class.new

我想要的最终结果是许多类的工作方式如下所示:

module MyMod
  class AA < Base
    def self.value
      value1
    end
  end

  class AB < Base
    def self.value
      value2
    end
  end

  ...
end

我目前的代码如下:

name = 'AA'
value = 'test'
MyMod.const_set name, Class.new(Base) do
  ???
end

设置名称效果很好,但是没有弄清楚我在块中获取value的内容。调用def不起作用,因为value的闭包得到了丢失。

我设法让事情得到了解决:

temp = const_set name, Class.new(Base)
temp.define_singleton_method(:value) { value }

但是,似乎应该有一种方法可以使用Class.new的块来实现。另外,我真的不确定define_singleton_method实际上是将方法放在正确的位置。它适用于我的测试,但我不确定该方法是否实际上是我认为的方式或调用链的其他地方。我尝试了class_variable_setattr_readerclass_evalinstance_eval和其他组合的各种组合,但它达到了猜测和检查的程度。我想我仍然没有完全围绕元编程: - /

1 个答案:

答案 0 :(得分:4)

如果我正确理解了您的问题,这应该适合您:

class Base
end

class AA < Base

  name = :Blah
  klass = self.const_set name, Class.new(Base)

  class << klass
    def value
      __method__
    end
  end

end

p AA::Blah.value
#=> :value

更新:似乎你想在块中定义它:

class Base
end

class AA < Base

  name = :Blah
  klass = Class.new(Base) do

    class << self
      def value
        __method__
      end
    end

  end
  self.const_set name, klass

end

p AA::Blah.value
你尝试这个:

const_set name, Class.new(Base) do
  ...
end

它不起作用,因为该块指的是const_set而不是Class.new

如果您希望define_singleton_method超过class << self

class Base
end

class AA < Base

  name = :Blah
  klass = Class.new(Base) do

    self.define_singleton_method :value do
      __method__
    end

  end
  self.const_set name, klass

end

最后,如果你真的想一次定义它们,请使用括号而不是do...end

class Base
end

class AA < Base

  name = :Blah
  self.const_set name, Class.new(Base) {

    self.define_singleton_method :value do
      __method__
    end

  }

end

Here是一个有效的演示