即使在 Ruby 中 IF 条件评估为假,如何创建局部变量? [英] How is a local variable created even when IF condition evaluates to false in Ruby?

查看:43
本文介绍了即使在 Ruby 中 IF 条件评估为假,如何创建局部变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 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 条件的计算结果为 falseblah 也被分配了 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 条件评估为假,如何创建局部变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆