ruby - 在 Ruby 中,对于未定义的变量“foo”,为什么“foo = foo”不会引发错误?
问题描述
Whenfoo
是一个未定义的变量,尝试访问它会引发NameError
:
foo
#=> NameError: undefined local variable or method `foo'
a = foo
#=> NameError: undefined local variable or method `foo'
为什么不foo = foo
提出一个NameError
?
foo = foo
#=> nil
昨天,我花了几个小时才找到这条线作为程序中的错误......
capture = capture.to_i
我原本打算做的是转换capture_str
为Integer
. 我所做的是nil
通过说引入 a capture = capture
,然后将 nil 变成 a 0
。所以我在做这个...
capture = capture.to_i
#=> 0
但我一直错误地假设NameError
会抛出一个变量,就像这样......
capture = capture_str.to_i
#=> NameError: undefined local variable or method `capture_str'
解决方案
Ruby 有一个奇怪的特性,它会在声明变量时提升变量:
这意味着当解析器看到 x=1 时,它实际上会声明该变量,将其分配给 nil 并让解释器确定 x = 1 行是否会被执行。
所以当你写
a = a.to_i
它首先声明a = nil
然后调用to_i
它并分配:
a = nil
a = a.to_i
编辑:
它在其他情况下也可以这样工作,例如if
:
pry> b
NameError: undefined local variable or method `b' for main:Object
from (pry):30:in `__pry__'
pry> b if b.nil?
NameError: undefined local variable or method `b' for main:Object
from (pry):31:in `__pry__'
pry> b = 1 if b.nil?
#=> 1
pry> b
#=> 1
和(来自链接的博客文章的示例):
if false
x = 1
end
puts x.class
# NilClass
推荐阅读
- python - Scipy 在结构化二维数据上进行插值,但在非结构化点进行评估?
- asp.net-core - ASP.NET 无法添加引用
- firebase - Flutter 中处理 Firebase 权限不足错误
- java - 如何在没有 location.reload() 的 POST 请求后刷新页面内容
- python - 熊猫如何根据索引值改变系列并保留其他系列值
- angular - 如何从 Angular 7 中的 url 字符串获取路由对象?
- java - 使用杰克逊反序列化包含 @JsonFormat(shape=JsonFormat.Shape.ARRAY) 和自定义对象的 json
- angular - 我的 Angular 应用程序使用 SSO 进行身份验证,它将标头中的用户详细信息返回给应用程序。如何解析传入的标头?
- oracle - 使用oracle正则表达式子字符串时检查表中是否存在值
- rails-activestorage - 即使在出错后也能保存主动存储附件