我有以下情况:
class A < CommonParent
... some code ...
class IdenticalDescendent < self
identical_statement_0
identical_statement_1
end
end
class B < CommonParent
... some other code ...
class IdenticalDescendent < self
identical_statement_0
identical_statement_1
end
end
我有很多这种情况。就像,我的应用程序中有大约40个IdenticalDescendent
类。我喜欢这种模式,它允许我调用A::IdenticalDescendent
或B::IdenticalDescendent
或其他任何内容来访问不同域中的某些相关行为(由A
或B
指定)。出于原因,我不能通过重新设计行为聚类来完全抽象问题。
因此,我的问题的一般形式是如何在所有这些中自动生成IdenticalDescendent。有CommonParent
的后代不会调用这种模式,所以这个动作可能不应该在那里发生。我想它应该发生在mixin或者其他什么东西,但我发现如果我只是尝试这样做:
class A < CommonParent
include CommonBehaviour
... some code ...
end
module CommonBehaviour
... what ...
end
我无法弄清楚如何编写CommonBehaviour
以允许IdenticalDescendent从包含类中继承。
帮助我StackOverflow,你是我唯一的希望。
答案 0 :(得分:1)
我正在寻找的答案是在Class.new
回调中对self.included
使用块表示法。我现在有这个:
module CommonDescendant
def self.included(base)
descendant_class = Class.new(base) do
... put my desired common behavior here ...
end
base.const_set :Descendant, descendant_class
end
end
class A
include CommonDescendant
... unique behavior ...
end
class B
include CommonDescendant
... unique other behavior ...
end
这给了我想要的设计!
答案 1 :(得分:0)
我相信您可以使用回调(挂钩)Class#inherited:
来自动化您的模式class CommonParent
def self.inherited(klass)
return unless klass.superclass == CommonParent
klass.const_set(:Descendent, Class.new(klass) do
def x
puts "in x"
end
end)
end
end
class A < CommonParent
def a
puts "in a"
end
end
d = A::Descendent.new #=> #<A::Descendent:0x007f99620172e8>
d.a # in a
d.x # in x
class B < CommonParent
def b
puts "in b"
end
end
d = B::Descendent.new #=> #<B::Descendent:0x007f99618b18f0>
d.b # in b
d.x # in x
d.a #=> NoMethodError:... (as expected)
请注意,没有:
return unless klass.superclass == CommonParent
创建A::Descendent
会触发inherited
klass => Descendent
,导致创建Descendent
的匿名子类等,导致“堆栈级别太深异常“。
答案 2 :(得分:-1)
我建议分离后代类和方法生成。当然,你可以把所有东西都扔进class_eval
区块(这将会积极地发现)。
类似以下内容(完全未经测试)
module CommonDescendants
Descendant = Class.new(self) do
include CommonDescendantMethods
end
end
module CommonDescendantMethods
end
class A < CommonParent
extend CommonDescendants
end