2014-02-11 47 views
0

我知道,我可以從模塊這樣我可以用模塊覆蓋實例方法嗎?

class Foo 
    class << self 
    def some_static_method 
     puts 'some_static_method' 
    end 
    end 
end 

module BAR 
    class << Foo 
    def some_static_method 
     puts 'another_static_method' 
    end 
    end 
end 

class Foo 
    include BAR 
end 

Foo.some_static_method # => 'another_static_method' 

覆蓋類的方法是否有可能爲一個實例方法?

+0

您可能會發現一些信息[這裏](http://stackoverflow.com/questions/5944278/overriding-method-by-another-defined-in-module)。 – maxdec

回答

1

你可以做到以下幾點:

class Foo 
    def self.some_static_method; puts "Hello from Foo" end 
end 

module Bar 
    def self.included(base) 
    base.instance_eval do 
    def some_static_method; puts "Hello from Bar" end 
    end 
    end 
end 

class Foo 
    include Bar 
end 

Foo.some_static_method 

這應該工作

UPDATE

要覆蓋實例方法使用:

class Foo 
    def some_instance_method; puts "Hello from Foo" end 
end 

module Bar 
    def self.included(base) 
    base.class_eval do 
    def some_instance_method; puts "Hello from Bar" end 
    end 
    end 
end 

class Foo 
    include Bar 
end 

Foo.new.some_instance_method 
+0

好的。這是更好的方法來覆蓋類方法。那麼,Foo類的實例方法呢? –

+0

查看更新的答案 –

1

你的問題其實不是方法覆蓋。它是關於模塊主體中的class ...構造中涉及的什麼類。

當您在主環境做

module Bar 
    class << Foo 
    p self 
    end 
end 
# => #<Class:Foo> 

<< Foo指向單例類的Foo因爲class << Foo不能直接定義並沒有預先定義的類Foo的單例類。因此它查找已經定義的Foo,並且在主環境中找到這樣的類。

當你

module Bar 
    class Foo 
    p self 
    end 
end 
# => Bar::Foo 

一個新的類創建Bar::Foo; Foo指向新創建的Bar::Foo,並且它不指向主環境中的Foo。爲了指出它,你必須明確地指定::

module Bar 
    class ::Foo 
    p self 
    end 
end 
# => Foo 
1

如果您使用的是Ruby> 2.0.0,那麼您可以使用的是Module#prepend。而不是include你可以prepend一個模塊,那麼所有模塊的方法都覆蓋任何現有的具有相同名稱的類實例方法。您可以看到一個快速示例here

此前紅寶石2時,Rails已經推出了類似黑客:#alias_method_chain

Here是兩種方法的比較不錯。

相關問題