【问题标题】:Ruby metaprogramming, defining multiple "inherited" functionsRuby 元编程,定义多个“继承”函数
【发布时间】:2010-09-09 18:50:36
【问题描述】:

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

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  

我想要实现的是我希望我的父类具有对直接子类的引用。我还需要其他东西在我的班级上设置的任何其他以前的“继承”方法来保持原位。我做错了什么?

【问题讨论】:

  • 你到底遇到了什么错误?
  • 原始方法没有被调用。

标签: ruby metaprogramming


【解决方案1】:

您的代码适用于这种情况(对我而言):

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 的子类也可以访问模块方法,但不要明确地 include 它。

您可以通过执行以下操作来解决此问题:

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]

也许它对您不起作用的原因是您在定义inherited 方法之前包含了InheritanceEnumerator

【讨论】:

  • 这是预期的行为,我不一定希望子类跟踪其子类。即使您声明了另一个“继承”函数,它是否也有效?
  • @MrZombie,更新后的答案能解决您的问题吗? :)
猜你喜欢
  • 2019-06-11
  • 2018-09-01
  • 2011-08-20
  • 2012-03-04
  • 2011-03-30
  • 1970-01-01
  • 1970-01-01
  • 2013-02-20
  • 2011-10-14
相关资源
最近更新 更多