2012-11-19 77 views
2

儘管多次嘗試,我無法使用define_method()創建一個方法並提供一個方法。使用define_method和下面的ruby文檔

如果我的理解是可以在這裏找到http://www.ruby-doc.org/core-1.9.3/Module.html的模塊類的文檔,我應該能夠做到以下任一操作:

define_method(符號,法)→NEW_METHOD

define_method(符號) {塊}→PROC

我能夠使用define_method(符號){塊}但是我收到似乎是一個方法(而不是在文檔概述了一個進程我掛):

class M 
    define_method(:hello) { puts "Hello World!"} 
end 

M.new.hello 

我在這裏的兩個問題是: 1.做上述我似乎並沒有收到一個proc,儘管文檔清楚地說明這就是我會得到的。 2.我不知道如何提供一個「define_method(符號,方法)→new_method」的方法,我試過Google搜索無濟於事,不知道如何使用這種形式的define_method。

如果任何人可以請擺脫這一點,將不勝感激! :) 非常感謝!

+0

你可以發佈你實際想要做的事嗎?從你發佈的小代碼中確實不清楚。 – meagar

+0

對我來說(1.9.3p194),運行'define_method(:foo){puts「foo」}'會返回一個proc:'=>#' – pje

+0

I我只跟隨rubymonk.com,這被證明是一個很好的資源,只是想了解我自己的關於define_method()和method()的更多信息,因爲我不確定我是否理解文檔,似乎define_method既可以定義一個實例方法,但仍然返回 – dreamwalker

回答

0

define_method確實會根據使用情況返回ProcMethod

在第一種情況中,Proc返回:

class Test 
    x = define_method :test_method { nil } 
    puts x.inspect 
end 


Test.new.test_method 

運行上面上的控制檯輸出:

#<Proc:[email protected]:3 (lambda)> 

第二種情況返回UnboundMethod,這是一種類型Method

class Test2 < Test 
    y = define_method :test_method2, Test.instance_method(:test_method) 
    puts y.inspect 
end 

Test2.new.test_method2 

上述輸出

#<UnboundMethod: Test#test_method> 

這是一個極其人爲的例子,並且限定的方法傳遞給define_method不是在這種情況下非常有用,我也不能認爲哪裏會的情況。

+0

當我運行第一個代碼示例我得到語法錯誤,意想不到的'{',期待keyword_end和一些奇怪的原因,我需要把:test_method放在括號中,無論如何,thx很多,這是很大的幫助:D,從來沒有想過調用Class_name.new實際上執行被類綁定的代碼,並因此使x.inspect得到執行(現在從Module繼承的類開始使整體更有意義:) ),一個proc被返回我仍然可以調用Test.new.test_method ... mhmmm相當了不起:) – dreamwalker

0

你可以在你的類中定義這樣的方法做到這一點:

class TestClass 
    def a_method 
    end 
    # Store the method in a class variable; define_method is a Module 
    # method and needs to be called from within this context 
    @@x = define_method(:another_method, TestClass.new.method(:a_method)) 
    def x 
    @@x 
    end 

    # And to get a block... 
    @@y = define_method(:yet_another_method) {} 
    def y 
    @@y 
    end 
end 

調用x方法,你會得到這樣的事情:

TestClass.new.x 
#<Method: TestClass#a_method> 

,而調用y方法,你能得到像這樣的東西:

TestClass.new.y 
#<Proc:[email protected](irb):75 (lambda)> 

這裏比較棘手的部分是,您需要一個來自同一類(或超類)的對象的方法,您正在執行define_method,否則它不起作用。舉例來說,如果你更換@@x行:

... 
@@x = define_method(:another_method, String.new.method(:gsub)) 
... 

因爲TestClass得到以下TypeError不是String一個子類:

TypeError: bind argument must be a subclass of String 

觀察,這工作:

... 
@@x = define_method(:another_method, Object.new.method(:object_id)) 
... 

輸出與此類似:

TestClass.new.x 
#<Method: Object(Kernel)#object_id> 

我認爲背後需要一個方法來自同一類層次的原因是執行面向對象的代碼封裝和隱私(否則,您可以通過從另一個類傳遞一個方法來訪問私有方法和變量)。