为什么在这个Ruby脚本中打印两次“hello”?

时间:2012-09-21 07:00:14

标签: ruby

我决定尝试在Ruby中定义方法内部的方法并写下这个:

def foo
  def bar
    puts "hello"
  end
  bar
end

这个定义,我跑了foo和“你好”按照我的预期打印。然而,我接着试了foo.bar - 两次打印出“你好”。为什么?

3 个答案:

答案 0 :(得分:4)

foo.bar等于foo().bar(),因此您首先调用包含foo的{​​{1}},以便在此处执行一次,然后再次执行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

这怎么可能?

编辑:正如在某些答案中所解释的那样,嵌套方法包含在类范围中,因此在foo内部或外部声明bar都没有任何区别。

Matz said也可能从Ruby2.0改变

这是他写的例子:

>> nil.bar
#=> hello

edit-Ruby2.0 :它最终没有实现。所以它仍然是一样的。

答案 1 :(得分:2)

在Ruby中,有一个隐藏的变量没有引起太多关注。我不知道它叫什么,但我把它称为当前的类。此变量是def

的目标

当你进入foo时,它不会改变这个变量,你仍然在同一个班级。因此,当您在foo中定义另一个方法时,该方法将在与定义foo相同的类上定义。

在这种情况下,你要在main,toplevel对象上定义foo。 Main的当前类变量设置为object,因此您在此处定义的任何方法都可以在任何对象中使用。

由于你做的最后一件事是返回bar的结果,而bar返回nil(b / c puts返回nil),然后foo.barnil.bar。既然你在Object上定义了bar,那么即使是nil也会继承这个方法。

有趣的是,酒吧是公共的。因为foo是在main中定义的,而main将其范围设置为private,所以我希望bar也是私有的,但我想这种状态必须在你去另一个范围时丢失。

答案 2 :(得分:1)

你的意思是放class foo吗?似乎调用foo.bar调用函数foo然后调用函数栏。调用nil.bar也打印出'hello'。