我正在尝试动态创建一组类,如下所示。
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
而不是手动创建每个类,e。 G:
class Alpha < Foo
def initialize
@description = 'Alpha'
end
end
执行此类操作的正确方法是什么?如何将迭代器传递给嵌套块?
答案 0 :(得分:1)
你很亲密。我想你想让description
成为一个类实例变量(或者可能是一个类变量),而不是实例变量。对于类description
的所有对象,Alpha
将为“Alpha”,因此它应该是类的属性。您可以Alpha.description
(或Alpha.new.class.description
)访问它。这是使用类实例变量的解决方案:
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
答案 1 :(得分:1)
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
答案 2 :(得分:1)
如何将迭代器传递给嵌套块?
使用嵌套的块。 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"
您也可以执行您想要的操作,而无需创建嵌套块或类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"