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"
我正在尝试动态创建一组 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"