在此示例中,
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
我收到“未定义的局部变量或方法”错误。
所以我的问题是为什么当我调用foo(3)并且从未设置bar时我没有收到此错误?
答案 0 :(得分:55)
这里发生了一些事情。首先,在if
块内声明的变量与在方法顶层声明的变量具有相同的局部范围,这就是bar
在if
之外可用的原因。其次,你得到了这个错误,因为bob
被直接引用了。 Ruby解释器从未见过它,也从未见过它。但是,它在if语句中之前已经初始化bar
。所以什么时候到吧,它知道它存在。结合这两个,这就是你的答案。
答案 1 :(得分:15)
你的第二个例子实际上是一个红色鲱鱼:你获得异常的原因不是因为bob
未初始化,而是因为它含糊不清。无法判断它是变量还是方法。
您的第一个示例有效,因为未初始化的局部变量(以及全局变量和实例变量)计算为nil
。因此,puts bar
完全正常:在一种情况下,bar
初始化为100
,此评估为100
,在另一种情况下,它未初始化,因此评估为{{ 1}}。 nil
在其参数上调用puts
,该参数是为to_s
定义的(它只返回空字符串),所以一切都很好而花花公子。
答案 2 :(得分:4)
所以不要把它当作福音(因为它更多地基于观察然后理解),但似乎红宝石解释器会在等号的左边标记任何单词(在它前面没有印记)作为一个地方。你的例子很奇怪,这更奇怪
def foo
bar = bar
puts bar // nil, which gets coerced into ""
end
我不明白为什么或如何运作,但你有它。
答案 3 :(得分:2)
foo(3)
不会输出任何内容。它输出换行符。
使用inspect
会给你更多提示:
def foo(x)
if(x > 5)
bar = 100
end
puts bar.inspect
end
foo(3)
打印出来
nil
bar
是一个完全成熟的变量,恰好有nil
的值。
答案 4 :(得分:0)
我不确定你在问什么。使用第二个定义运行foo(3)
将始终给出错误,因为永远不会定义bob
。该方法的参数不会改变它。