为什么在下面的代码片段foo取代了它的定义?
def foo
def foo
1
end
end
第一次foo
为零
foo
=> nil
foo.foo
=> 1
现在,如果我再次致电foo
:
foo
=> 1
正如您所看到的,foo
不再是零。谁可以给我解释一下这个?感谢。
答案 0 :(得分:7)
def foo
p "about to redef foo"
def foo
1
end
end
foo
"about to redef foo"
=> nil
foo
=> 1
此外,当您致电foo.foo
时,您似乎正在尝试访问内部foo
方法,但它无法正常工作。您的foo
方法实际上已在Object
上定义,因此您实际上正在调用1.foo
。
答案 1 :(得分:1)
如果您想要这种效果,请尝试
def foo
foo = proc {
1
}
end
由于def
方法不会创建新的self
。每个方法都受到约束
到self
,在这种情况下是main
,是一个Object.new
为ruby解释器加载的每个文件实例化。里面一个
class,self
是类,你得到实例方法。
答案 2 :(得分:1)
方法定义在读取时进行解析,但在调用之前不会执行。当您执行第一个foo
时,会执行最外面的foo
,将Object#foo
定义为
def foo
1
end
并返回nil
作为定义方法的操作的返回值。从那时起,当您调用foo
时,将执行新定义的foo
,并返回
1
答案 3 :(得分:0)
当您第一次致电foo
时,它会返回方法foo
,当您再次致电foo
时,它会返回1。
阅读closure
答案 4 :(得分:0)
ruby中的嵌套方法定义令人困惑。
它们实际上是重新定义!
两种定义都适用于最外层的情况。这两个定义都定义了相同的(!)方法foo。虽然在读取文件时会解释外部定义,但只在第一次调用外部方法时才会解释内部定义。然后它将取代初始定义。
鉴于此代码
def foo
def foo
1
end
end
让我们来看看:
foo
定义全局方法def foo; 1; end
。当您致电foo()
时,会执行此全局方法并使用正文foo
重新定义全局方法 1
,并返回{{1因为定义一个方法没有返回值。
当你调用nil
时,执行全局方法并返回foo().foo()
,再次执行全局方法,再次返回1
。
这里有两点困惑:a)嵌套方法定义既适用于同一外部作用域,又b)可以在任何对象上调用全局方法。
这是另一个展示嵌套定义如何实际重新定义的例子。
1
这是发生的事情
class A
def m(arg=nil)
def m; 42; end if arg
23
end
end
如您所见,嵌套定义实际上是一种重新定义。
答案 5 :(得分:0)
我个人总是认为它在类上定义内部def
是非常奇怪的。我认为在单身人士上定义它更为明智。例如相当于def self.foo
,因为它是在实例级别而不是类级别调用的。
或者它只能从它定义的方法中调用 - 虽然因为我们有lambdas而可能没那么有用。
但有一件事是肯定的,你几乎不会在实践中看到这一点。