Ruby:动态创建新的类

Ruby: Dynamically create new classes

我正在尝试动态创建一组 classes,如下所示。

class Foo
    attr_reader :description
end

['Alpha', 'Beta', 'Gamma'].each do |i|
  klass = Class.new(Foo) do |i|
    def initialize
      @description = i
    end
  end
  Object.const_set(i, klass)
end

而不是手动创建每个 class,e。 g.:

class Alpha < Foo
  def initialize 
    @description = 'Alpha'
  end
end

做这样的事情的正确方法是什么?如何将迭代器传递给嵌套块?

你很接近。我认为您想使 description 成为 class 实例变量(或者可能是 class 变量),而不是实例变量。对于 class Alpha 的所有对象,description 将是 "Alpha",因此它应该是 class 的属性。您将以 Alpha.description(或 Alpha.new.class.description)的形式访问它。这是使用 class 实例变量的解决方案:

class Foo
  class << self
    attr_reader :description
  end
end

['Alpha', 'Beta', 'Gamma'].each do |i|
  klass = Class.new(Foo)
  klass.instance_variable_set(:@description, i)

  Object.const_set(i, klass)
end
class Foo
  attr_reader :description
end

['Alpha', 'Beta', 'Gamma'].each do |class_name|
  eval %Q{
    class #{class_name} < Foo
      def initialize
        @description = #{class_name}
      end
    end
    }
end

执行时:

Gamma.new.description
 => Gamma 

how do I pass an iterator to a nested block?

通过使用嵌套的。 def 不是块。 def 切断了 def 之外的变量的可见性。另一方面,可以看到块外的变量:

class Foo
    attr_reader :description
end

['Alpha', 'Beta', 'Gamma'].each do |class_name|
  klass = Class.new(Foo) do 
    define_method(:initialize) do
      @description = class_name
    end
  end

  Object.const_set(class_name, klass)
end

a = Alpha.new
p a.description

--output:--
"Alpha"

您也可以做您想做的事,而无需创建嵌套块或 class Foo:

['Alpha', 'Beta', 'Gamma'].each do |class_name|
  klass = Class.new() do
    def initialize
      @description = self.class.name
    end

    attr_reader :description

  end

  Object.const_set(class_name, klass)
end

--output:--
"Alpha"
"Gamma"