Ruby元编程,定义多个 "inherited"函数

标签 ruby metaprogramming

我希望将以下模块包含在我拥有的类中:

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/

相关文章:

c++ - 一个类可以通过什么方式访问另一个类的成员?

ruby - 方法闭包似乎在 therubyracer 中不起作用

html - Bootstrap 嵌套下拉列表

这个的 ruby 快捷方式?

ruby - 如何将 ruby​​ BigDecimal 转换为 2 位小数位字符串?

c++ - 对参数包中的每个元素应用函数

mysql - 使用 id 从表中检索值

c++ - 如何知道一个类型是否是 std::vector 的特化?

python - 以编程方式为类生成方法

reflection - 如何获取模块的所有成员/函数?