我希望将以下模块包含在我拥有的类中:
module InheritanceEnumerator
def self.included(klass)
klass.instance_eval do
instance_variable_set('@subclasses',[])
def self.subclasses
@subclasses
end
original_method = self.respond_to?(:inherited) ? self.public_method(:inherited) : nil
instance_variable_set('@original_inherited_method', original_method)
def self.inherited(subclass)
@original_inherited_method.call(subclass) if @original_inherited_method
@subclasses<<subclass
end
end
end
end
我想要实现的是,我希望我的父类能够引用直接子类。我还需要其他东西在我的类(class)上设置的任何其他以前的“继承”方法以保留原位。我做错了什么?
最佳答案
您的代码在这种情况下(对我而言)有效:
class C; include InheritanceEnumerator; end
C.subclasses #=> []
class C1 < C; end
class C2 < C; end
C.subclasses #=> [C1, C2]
但在以下情况下失败:
class C11 < C1; end
C1.subclasses => NoMethodError: undefined method `<<' for nil:NilClass
这是因为您只在包含模块时才初始化@subclasses
;但是您忘记了 C
的子类也可以访问模块方法,但没有明确地包含
它。
您可以通过执行以下操作来解决此问题:
def self.subclasses
@subclasses ||= []
@subclasses
end
def self.inherited(subclass)
@original_inherited_method.call(subclass) if @original_inherited_method
@subclasses ||= []
@subclasses << subclass
end
编辑:
好的,以后请把你的问题说的更全面一些,并提供你正在使用的测试代码;因为这是一次令人沮丧的练习。
以下代码适用于您的代码:
class C
def self.inherited(s)
puts "inherited by #{s}!"
end
include InheritanceEnumerator
end
class D < C; end #=> "inherited by D!"
C.subclasses #=> [D]
也许它对您不起作用的原因是您包含了 InheritanceEnumerator
在您定义inherited
方法之前?
关于Ruby元编程,定义多个 "inherited"函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3679633/