2013-10-14 44 views
19

試圖在initialize內使用define_method,但得到undefined_method define_method。我究竟做錯了什麼?如何在初始化中使用define_method()

class C 
    def initialize(n)  
    define_method ("#{n}") { puts "some method #{n}" }  
    end 
end 

C.new("abc") #=> NoMethodError: undefined method `define_method' for #<C:0x2efae80> 
+0

你想做什麼? –

+2

沒有具體的,試圖看看我可以使用'define_method'動態定義一個方法。 – Bala

回答

20

做如下:

class C 
    def initialize(n)  
    self.class.send(:define_method,n) { puts "some method #{n}" }  
    end 
end 

ob = C.new("abc") 
ob.abc 
# >> some method abc 

Module#define_method私有方法也是一個 method.Your一個沒有工作,因爲你試圖調用它的實例C。您必須在C上撥打電話,在您的情況下使用#send

+1

它的工作原理。你能解釋爲什麼我的早期版本不正確嗎? – Bala

+1

@Bala:請注意,o = C.new('pancakes')'會將'ob.abc','ob.pancakes','o.abc'和'o.pancakes'作爲有效的方法調用。大家都確定這是意圖嗎? –

+1

@ muistooshort:有趣的評論。儘管沒有意圖,但現在我正在考慮如何使它具體化(單例)。 – Bala

33

我懷疑你正在尋找define_singleton_method

define_singleton_method(符號,法)→NEW_METHOD
define_singleton_method(符號){}塊PROC→

定義一個單方法在接收器中。 方法參數可以是ProcMethodUnboundMethod對象。如果指定了塊,則將其用作方法主體。

如果您在使用self.classdefine_method,您將創建新的方法,對整個類的實例方法,因此將作爲在類的所有實例的方法。

你會使用define_singleton_method這樣的:

class C 
    def initialize(s)  
    define_singleton_method(s) { puts "some method #{s}" }  
    end 
end 

然後:

a = C.new('a') 
b = C.new('b') 
a.a # puts 'some method a' 
a.b # NoMethodError 
b.a # NoMethodError 
b.b # puts 'some method b' 

如果您initialize那樣:

self.class.send(:define_method,n) { puts "some method #{n}" }  

,那麼你會得到:

a.a # puts 'some method a' 
a.b # puts 'some method b' 
b.a # puts 'some method a' 
b.b # puts 'some method b' 

這可能不是你要找的。創建一個新的實例並讓整個班級變化的結果很奇怪。