2010-09-09 61 views
4

我要包含在類中的下列模塊的功能,我有:紅寶石元編程,定義多個「繼承」

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 

我想要實現的是,我希望我的父類中有引用指導兒童。我還需要其他的東西在我的課堂上設置的任何其他「繼承」方法,以保持原地。我究竟做錯了什麼?

+0

你準確得到了什麼錯誤? – horseyguy 2010-09-10 13:37:17

+0

原始方法不會被調用。 – 2010-09-10 15:52:52

回答

2

您的代碼在這種情況下工作(對我來說):

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] 

也許它不是爲你工作的原因是,你包括之前InheritanceEnumerator您已經定義的inherited方法?

+0

這是預期的行爲,我不一定希望子類跟蹤其子類。即使你聲明瞭另一個「繼承」函數,它是否工作? – 2010-09-10 15:44:07

+0

@MrZombie,更新的答案是否對您的問題做出迴應? :) – horseyguy 2010-09-11 07:01:31