块中定义的方法属于哪个class?

Which class does a method defined inside a block belong to?

这是一个 class

class Foo
  def test_method(&c)
    puts "inside test method"
    c.call
  end
end 

现在,如果我在块中定义一个方法

f = Foo.new
f.test_method do 
  def m1
    puts "inside the method m1 defined inside the block"
  end
  puts m1.class
end

块的输出是NilClass

如果一个方法定义在 class 之外,它将成为 class Object 内部的私有方法。为什么块内定义的方法成为 NilClass 的一部分而不是 class Foo 的一部分?

如果你想检索 class 定义的方法,你应该明确地做:

Foo.new.test_method do 
  def m1; :content_does_not_matter; end
  puts method(:m1).inspect
end  
#⇒ #<Method: Object#m1>

可以使用 Method#owner 检索所有者:

method(:m1).owner
#⇒ Object

首先,m1returnsputs的结果,即nil

其次,使用您当前的代码,m1 方法是为 Object class 定义的,因为默认情况下块保留其上下文,而不仅仅是局部变量(它始终如此) ),还有 'current object' 和 'current class'。如果您希望您的定义按预期工作,您可以使用 class_eval,它会更改块内的当前 class(在不同的上下文中执行此块:

class Foo
  def test_method(&c)
    puts 'inside test method'
    self.class.class_eval(&c)
  end
end
f = Foo.new
f.test_method do
  def m1
    # anything
  end
end

Foo.instance_methods.grep(/m1/)
# => [:m1]
f.m1
# => not an error
Object.new.m1
# => NoMethodError: undefined method `m1' for #<Object:0x00000001c9b4f8>