2009-12-11 57 views
41
obj = SomeObject.new 

def obj.new_method 
    "do some things" 
end 

puts obj.new_method 
> "do some things" 

此工作正常。不過,我需要做一個現有的方法中同樣的事情:將方法添加到實例化對象

def some_random_method 
    def obj.new_method 
    "do some things" 
    end 
end 

確定工作爲好,但有一個方法中的方法看起來相當可怕。問題是,是否有添加這種方法的替代方法?

+0

你確定代碼的第二片段的作品?因爲我想它應該首先接受'obj'作爲方法參數來定義一個單例方法。 – Chirantan 2009-12-11 12:57:45

回答

66

這是一個很長的時間,因爲我問這個。在紅寶石1.9+,還有通過使用define_singleton_method這樣做的更好的方法,具體如下:

obj = SomeObject.new 

obj.define_singleton_method(:new_method) do 
    "do some things" 
end 
+2

如果我在這個'do'塊中使用'@ field',會發生什麼?我會從當前類訪問一個字段,還是會使用'obj'字段? – ciembor 2013-01-31 10:30:54

+1

還沒有真正地測試過這個,但據我可以告訴mixin這種方法是不相同的。這可以訪問外部值,而mixin則不會。 – vise 2013-01-31 13:10:53

43

使用Mixin。

module AdditionalMethods 
    def new_method 
    "do some things" 
    end 
end 

obj = SomeObject.new 
obj.extend(AdditionalMethods) 

puts obj.new_method 
> "do some things" 
6

您可以使用模塊。

​​

現在,如果您需要向該對象添加更多方法,您只需要在模塊中實現方法並完成即可。

7

只是一個有趣的一點:

,如果你已經代替了:

def my_method 
    def my_other_method; end 
end 

然後my_other_method實際上就沒有頂住那的my_method接收機爲實例對象的類定義。

但是如果你去(像你一樣):

def my_method 
    def self.my_other_method; end 
end 

然後my_other_method是在實例的eigenclass定義。

沒有直接關係到你的問題,但很有趣儘管如此;)