我不明白ruby的本地范围
在这个例子中,
def foo(x) if(x > 5) bar = 100 end puts bar end
然后foo(6)输出:100和foo(3)什么都不输出。
但是,如果我改变了定义
def foo(x) if(x > 5) bar = 100 end puts bob end
我得到一个“未定义的本地variables或方法”错误。
所以我的问题是为什么我没有得到这个错误,当我打电话富(3)和酒吧从未设置?
有几件事情在这里发生。 首先,在if
块中声明的variables与在方法顶层声明的variables具有相同的局部范围,这就是为什么bar
在if
外部可用的原因。 其次,你会得到这个错误,因为bob
是被直接引用的。 Ruby解释器从来没有见过它,从来没有见过它初始化之前。 但是,在if语句之前,它已经看到了bar
初始化。 所以什么时候得到禁止它知道它存在。 结合这两个,这就是你的答案。
你的第二个例子实际上是一个红鲱鱼:你得到一个exception的原因不是因为bob
是未初始化的,这是因为它是模糊的。 不可能判断它是一个variables还是一个方法。
你的第一个例子工作,因为未初始化的本地variables(以及全局variables和实例variables)计算nil
。 因此, puts bar
是完全正确的:在一种情况下, bar
被初始化为100
并且这个值为100
,在另一种情况下,它是未初始化的,因此评估nil
。 puts
它的参数调用to_s
,这个参数定义为nil
(它只是返回空string),所以一切都很好,很花哨。
另请参阅在Ruby中,为什么在启动irb之后,foo.nil? 说未定义的错误,和@ foo.nil? 给出“真实”,和@@ wah.nil? 再次发生错误?
所以不要把它当做福音(因为它更多的是基于观察和理解),但是似乎ruby解释器会在等号的左边标记任何单词(前面没有印记)作为本地。 你的例子很奇怪,这更奇怪
def foo bar = bar puts bar // nil, which gets coerced into "" end
我不明白为什么或者它是如何工作的,但是在那里。
foo(3)
不会输出任何内容。 它输出一个换行符。
使用inspect
会给你更多的提示:
def foo(x) if(x > 5) bar = 100 end puts bar.inspect end foo(3)
打印出来
nil
bar
是一个完全成熟的variables,恰好有nil
的值。
我不确定你在问什么 用第二个定义运行foo(3)
总会给出一个错误,因为bob
永远不会被定义。 该方法的论点不会改变这一点。