问题描述
在 irb 中尝试以下操作:(我使用的是 Ruby 2.0.0-p247)
Try the following in irb: (I'm using Ruby 2.0.0-p247)
blah
#=> NameError: undefined local variable or method `blah' for main:Object
if false
blah = 'blah'
end
#=> nil
blah
#=> nil
令我感到惊讶的是,即使 if
条件的计算结果为 false
,blah
也被分配了 nil
.我认为 if
中的代码被跳过,因为条件评估为 false
.
I'm surprised that blah
is assigned nil
even when the if
condition evaluates to false
.I thought the code within if
is skipped as the condition evaluates to false
.
有 Ruby 内部知识的人可以解释一下这是怎么发生的吗?
Could someone with Ruby internals knowledge kindly explain how this happened?
谢谢
推荐答案
ruby 中的局部变量是在解析/编译代码(而不是执行)期间创建的.它们是词法范围的,所以局部变量在它被分配到的行之前是不可见的.
Local variables in ruby are created during parsing/compilation of code (not execution). They are lexically scoped, so a local variable is not visible before the line where it's assigned to.
defined?(foo) # => nil
if false
defined?(foo) # =>
foo = 'blah'
defined?(foo) # =>
end
defined?(foo) # => "local-variable"
foo # => nil
defined?(foo)
内的 if
行什么都不返回,因为它们没有运行.任务也没有执行.但是,编译器看到了对局部变量的赋值并创建了一个(默认值为 nil
).
defined?(foo)
lines inside of if
return nothing, because they didn't run. The assignment wasn't executed as well. However, the compiler saw the assignment to local variable and created one (with default value of nil
).
这种行为解释了 WAT talk 中的技巧:
This behaviour explains the trick from WAT talk:
a = a # => nil
即使变量 a
不存在,它也会在这一行之前创建(并设置为 nil),仅仅是因为代码中有一个赋值表达式(其目标尚不可知)局部变量).因此,当计算此表达式的右侧时,a
已存在.
Even though variable a
doesn't exist, it is created (and set to nil) right before this line, simply because there is an assignment expression in the code (target of which is yet unknown local variable). So by the time the right hand side of this expression is evaluated, a
exists.
这篇关于即使在 Ruby 中 IF 条件评估为假,如何创建局部变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!