2012-07-07 25 views
0

鑑於以下類Ruby Metaprogramming:檢查是否由父類調用?

class Parent 
    def hello 
    puts "I am the parent class" 
    end 

    def call_parent_hello 
    hello 
    end 
end 

class Child < Parent 
    def hello 
    puts "I am the child class" 
    end 
end 

當我執行以下操作:

c = Child.new 
c.hello    # => Outputs: "I am the child class" 
c.call_parent_hello # => Outputs: "I am the child class" 

是否有可能使Child#call_parent_hello訪問Parent#hello但不改變Parent類?

我要尋找某種called_by_parent_class?實現這樣的:

def hello 
    if called_by_parent_class? 
    super 
    else 
    puts "I am the child class" 
    end 
end 

回答

1

可以使用super關鍵字:

class Child < Parent 
    def hello 
    super 
    end 
end 
+0

這將輸出'「我是父類」'2倍。我希望第一次調用輸出'「我是孩子班級」',第二次打印'「我是父母班級」'。 – iblue 2012-07-07 17:28:16

+0

伊斯蘭會議組織。那麼,我只是錯誤的方法,那麼你需要重寫'call_parent_hello'。關鍵是你的問題的答案是「使用'super'關鍵字!」你可能喜歡閱讀這篇關於Ruby的方法查找過程的文章http://blog.rubybestpractices.com/posts/gregory/030-issue-1-method-lookup.html – 2012-07-07 17:44:13

+0

(看着你更新的「我在找什麼.. 。「問題) - 你可以使用'Kernel.caller'(但在幾乎所有情況下,這是一個設計錯誤) – 2012-07-07 17:50:07

0
  1. 使用supersuper調用父類

    class Child < Parent 
        def call_parent_hello 
        super 
        end 
    end 
    
  2. 使用直接調用層次相同的方法。 Class#ancestors爲您提供了繼承的層次結構。

    class Child < Parent 
        def call_parent_hello 
        self.class.ancestors[1].new.hello 
        end 
    end 
    
+0

其實我正在尋找某種'def你好;如果被調用__ __ __ __ __ __ class?超;否則將「我是孩子階級」;結束' – iblue 2012-07-07 17:34:18

+0

由父類調用? – texasbruce 2012-07-07 18:07:44

1

我想你希望做這樣的事情:

class Parent 
    def hello(opts = '') 
    "Who's talking? The #{self.class} class is via the Parent class!" 
    end 
end 

class Child < Parent 

    def hello(opts = '') 
    if opts == 'super' 
     super 
    else 
     "I have a parent and an independent voice" 
    end 
    end 

    def call_mom 
    hello('super') 
    end 

end 

c1 = Child.new 

puts c1.hello  => "I have a parent and an independent voice" 
puts c1.call_mom => "Who's talking? The Child class is via the Parent class!" 

但是(我不是在這裏曳)我也覺得你有種缺少點子類化。通常你可以繼承這個方法的自動範圍。如果你打破了這一點,我想你會想實例化一個父實例。但每一個他自己。

祝你好運!

+0

這裏的要點是,我有一個ActiveRecord模型。包含多個項目的發票。我可以將項目標記爲已刪除,並且我希望我的Invoice類中的items方法不會將已標記爲已刪除的項目返回。但是,超類仍然需要查看已刪除的項目,以便實際刪除它們。 這就是爲什麼我不能修改父類。 – iblue 2012-07-07 20:44:10

+0

再次不拖車...我只是想了解這個問題。你不能通過子對象中的「已刪除」列和已定義的名爲已刪除的範圍來實現此行爲。然後在父模型中調用「Child.deleted」。這聽起來更像是關聯問題與適當的子類別。再次,我不知道你的特定問題,但根據我的經驗,Rails中最常見的SubClassing使用是兩個幾乎相同的模型,但是子項具有額外的屬性。 (又名STI)例如,一篇報紙文章可以分爲OpEd和Feature – engineerDave 2012-07-08 17:55:24

+0

這不是關於刪除的專欄。我正在使用[mark_for_destruction](http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html#method-i-mark_for_destruction)將一些奇怪的MongoDB風格的行爲轉化爲ActiveRecord。我現在通過使用調用者來解決這個問題。見本要點的第52行:https://gist.github.com/3072127 – iblue 2012-07-08 18:16:06

1

重讀你的問題後,我看到你真正的問題是:

是否有可能使兒童#call_parent_hello訪問父#招呼,但沒有改變父類?

改變你的子類是:

class Child < Parent 
    alias_method :call_parent_hello, :hello 

    def hello 
    puts "I am the child class" 
    end 
end 

解決這個問題,就像你問