2009-04-29 55 views
28

在Ruby中,有沒有一種方法可以使用proc重新定義某個類的特定實例的方法?例如:使用lambda重新定義單個實例上的單個ruby方法

class Foo 
    def bar() 
    return "hello" 
    end 
end 

x = Foo.new 
y = Foo.new 

(喜歡的東西):

y.method(:bar) = lambda { return "goodbye" } 

x.bar 
y.bar 

生產:

hello 
goodbye 

感謝。

回答

40
def define_singleton_method_by_proc(obj, name, block) 
    metaclass = class << obj; self; end 
    metaclass.send(:define_method, name, block) 
end 
p = proc { "foobar!" } 
define_singleton_method_by_proc(y, :bar, p) 

,或者,如果你想猴子補丁對象,以方便

class Object 
    # note that this method is already defined in Ruby 1.9 
    def define_singleton_method(name, callable = nil, &block) 
    block ||= callable 
    metaclass = class << self; self; end 
    metaclass.send(:define_method, name, block) 
    end 
end 

p = proc { "foobar!" } 
y.define_singleton_method(:bar, p) 
#or 
y.define_singleton_method(:bar) do 
    "foobar!" 
end 

,或者,如果要定義你的PROC內聯,這可能是更具可讀性

class << y 
    define_method(:bar, proc { "foobar!" }) 
end 

class << y 
    define_method(:bar) { "foobar!" } 
end 

這是mo ST可讀,但可能不適合您的需求

def y.bar 
    "goodbye" 
end 

This question is highly related

15

您可以使用語法class <<object獲取對象的「單例類」(這是隻屬於該對象的一個​​特殊父類)和僅爲該實例定義方法。例如:

str1 = "Hello" 
str2 = "Foo" 

class <<str1 
    def to_spanish 
    'Hola' 
    end 
end 

現在,如果你這樣做str1.to_spanish,它將返回「HOLA」,但str2.to_spanish會給你一個NoMethodFound例外。

+0

如果他在一個簡單變量中有一個外部定義的過程,很難將其引入由<< str1創建的新範圍,而不訴諸全局或實例變量 – 2009-04-29 20:13:39

19

我不知道是什麼版本的Ruby這是在加入(至少1.8.7),但似乎有這樣做的更簡單的方法:

str1 = "Hello" 
str2 = "Goodbye" 
def str1.to_spanish 
    "Hola" 
end 
puts str1 # => Hello 
puts str1.to_spanish # => Hola 
puts str2 # => Goodbye 
puts str2.to_spanish # => Throws a NoMethodError 

得知這個情況後,同時閱讀Ruby Koans(about_class_methods.rb課程)。 我仍然不完全確定這是什麼目的,因爲它對我來說似乎有點危險。

+0

感謝您發佈此(更多)最新日期答案! – 2015-03-29 23:15:55

相關問題