2016-02-25 95 views
0

我有Delegator果然與Kernel.respond_to?Kernel.instance_methodRuby代理。定義調用方法類/模塊外:NameError

def some_func 
    puts '12' 
end 

puts ::Kernel.respond_to?(:some_func, true) #=> true 
::Kernel.instance_method(:some_func) #=> `instance_method': undefined method `some_func' for module `Kernel' (NameError) 

一個問題,原來在這種情況下發現了一個問題:

def some_func 
    puts '12' 
end 

class Klass < Delegator 
    def initialize(obj) 
    @obj = obj 
    end 

    def __getobj__ 
    @obj 
    end 

    def func 
    some_funC#=> `instance_method': undefined method `some_func' for module `Kernel' (NameError) 
    end 
end 

Klass.new(0).func 

我猜Kernel.respond_to?(:some_func)是真的,因爲我們的確可以稱之爲Kernel。並且instance_method嘗試採用在Kernel本身定義的方法(這不是這種情況)。

但我想知道爲什麼Delegator使用Kernel.respond_to?來檢查方法是否存在,Kernel.instance_method來調用它? (https://github.com/ruby/ruby/blob/trunk/lib/delegate.rb#L85

- = =更新 - 我創建了一個Ruby的錯誤追蹤系統裏的問題https://bugs.ruby-lang.org/issues/12113

+0

該代碼在Ruby 2.3.0中爲我生成了正確的結果。 – tadman

+0

那麼你複製粘貼這段代碼並且沒有錯誤地運行它?這很奇怪。你在使用什麼操作系統? –

+0

對於像這樣簡單的代碼,OS幾乎不是一個因素。你在使用Ruby 2還是更好? – tadman

回答

0

你檢查錯了地方。有

Kernel.methods & [ :some_func ] 
# => [:some_func] 

是:當你這樣定義它不instance_methods下顯示出來的方法,你不處理內核的實例,因爲這是一個模塊,而是此地。

+0

'Kernel.method(:some_func)'也適用。 –

+0

'method'方法用於獲取有關特定方法的更多信息,例如'Kernel.method(:some_func).source_location',但它也適用於這種情況。 – tadman

+0

是的,我知道它是什麼。 OP詢問爲什麼'Kernel.instance_method(:some_func)'不起作用,你的答案解釋了這一點,但我想指出,在這種情況下'*將*'起作用的'instance_method'等同於'method'。 –

相關問題