我决定尝试在 Ruby 中的方法中定义方法并写下:
def foo
def bar
puts "hello"
end
bar
end
这个定义,我跑了foo
,“你好”按我的预期打印了。但是我然后尝试foo.bar
了 - 它打印了两次“你好”。为什么?
我决定尝试在 Ruby 中的方法中定义方法并写下:
def foo
def bar
puts "hello"
end
bar
end
这个定义,我跑了foo
,“你好”按我的预期打印了。但是我然后尝试foo.bar
了 - 它打印了两次“你好”。为什么?
foo.bar
等于foo().bar()
所以你首先调用foo
包含bar
所以它在这里执行一次,然后再bar
执行一次。最后bar
被调用两次。
def foo
puts 'foo called'
def bar
puts 'bar called'
puts "hello"
end
bar
end
foo.bar
#=> foo called
#=> bar called
#=> hello
#=> bar called
#=> hello
我不明白的是这意味着结果foo
是nil
可以调用bar
。
>> nil.bar
#=> hello
这怎么可能?
编辑:正如一些答案中所解释的,嵌套方法包含在类范围内,因此在 foo 内部或外部声明 bar 没有任何区别。
Matz 也表示可能会从 Ruby2.0 更改
这是他写的例子:
class Foo
def foo
def bar
#omited
end
bar # can be called
end
def quux
bar # cannot be called
end
end
edit-Ruby2.0:最终没有实现。所以它保持不变。
在 Ruby 中,有一个隐藏变量并没有引起太多关注。我不知道它叫什么,但我称它为当前类。这个变量是目标def
当你进入 时foo
,它不会改变这个变量,你仍然在同一个班级。因此,当您在 foo 中定义另一个方法时,该方法将被定义在与 foo 定义相同的类上。
在这种情况下,您在顶级对象 main 上定义 foo。Main 的当前类变量设置为 object,因此您在此处定义的任何方法都将在任何对象中可用。
由于你做的最后一件事是返回 bar 的结果,而 bar 返回 nil(b/c puts 返回 nil),那么foo.bar
is nil.bar
。而且由于您在 Object 上定义了 bar,因此即使 nil 也会继承此方法。
有趣的是,酒吧是公开的。由于 foo 是在 main 中定义的,并且 main 将其范围设置为私有,我本来希望 bar 也是私有的,但我想一旦你进入不同的范围,状态肯定会丢失。
你的意思是放class foo
?似乎调用 foo.bar 调用函数 foo 然后调用函数 bar。呼叫nil.bar
也会打印出“你好”。