2016-02-25 69 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'。 –

相关问题