我得到 NameError: undefined local variable or method
with ruby 2.1.2
正如在 this question 中观察到的那样, 表达式如:
bar if bar = true
引发未定义的局部变量错误(前提是 bar
之前未定义),因为 bar
在分配之前被解析器读取。而且我相信以前用这个表达式没有什么区别:
bar if bar = false
两者之间的区别在于主体是否被求值,但如果遇到未定义的局部变量会在求值条件之前立即引发错误,那应该无关紧要。
但是当我在 Ruby 2.1.2 上运行第二个代码时,它没有引发错误。以前也是这样吗?如果是这样,那么解析讨论的内容是什么?如果没有,Ruby 规范是否改变了?有什么引用吗?它在 1.8.7、1.9.3 等版本中做了什么?
最佳答案
bar
是否定义没有区别。在这两种情况下,bar
在正文中都是未定义的。然而,在后一种情况下, body 永远不会被评估,因此无关紧要。您永远不会解析名称 bar
,因此在名称解析期间您永远不会遇到错误。
局部变量是在解析赋值时定义的。 它们在执行时被初始化。
变量被单元化是完全没问题的。在这种情况下,它只会评估为 nil
:
if false
bar = 42
end
bar
# => nil
但是,如果变量是undefined,那么 Ruby 不知道一个 bare word 是一个局部变量还是一个 receiverless argumentless 消息发送:
foo
# NameError: undefined local variable or method `foo'
# ^^^^^^^^^
# Ruby doesn't know whether it's a variable or a message send
比较:
foo()
# NoMethodError: undefined method `foo'
# ^^^^^^^^^^^^^
self.foo
# NoMethodError: undefined method `foo'
# ^^^^^^^^^^^^^
现在在一起:
foo()
# NoMethodError: undefined method `foo'
self.foo
# NoMethodError: undefined method `foo'
foo
# NameError: undefined local variable or method `foo'
if false
foo = 42
end
foo
# => nil
foo = :fortytwo
foo
# => :fortytwo
在这种特殊情况下,问题在于表达式被解析的顺序(以及变量定义的顺序)不与顺序匹配表达式在其中执行。
赋值首先执行,这会让您假设 bar
将在正文中定义。但它不是,因为正文首先被解析,因此一个我不知道这是一个方法还是一个变量节点被插入到语法树中< em>在作业被看到之前。
但是,如果该节点从未被解释过,即条件为假,那么就不会发生任何坏事。
关于ruby - 名称错误 : undefined - have parsing rules for local variables changed in Ruby 2. 1.2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25306902/