1

这里有一堂课

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

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

4

2 回答 2

4

首先,m1返回 的结果puts,即nil

其次,使用您当前的代码,m1Object类定义了方法,因为默认情况下块仍然是其上下文,不仅用于局部变量(它总是如此),而且还用于“当前对象”和“当前类”。如果您希望您的定义按预期工作,您可以使用class_eval,它会更改块内的当前类(在不同的上下文中执行此块:

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>
于 2018-07-24T11:55:52.833 回答
0

如果要检索定义该方法的类,则应显式执行:

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
于 2018-07-24T11:54:57.950 回答