【问题标题】:Strange meaning of || and ||= in Ruby (2.0, 1.9.3, jruby 1.7.4)||的奇怪含义和 ||= 在 Ruby (2.0, 1.9.3, jruby 1.7.4)
【发布时间】:2013-10-26 01:24:54
【问题描述】:

从新开始的会话中考虑以下 irb sn-p:

irb:01> baz            # => NameError, baz is not defined
irb:02> baz || baz = 0 # => NameError, baz is not defined
irb:03> baz            # => nil

baz 是一个未定义的变量,尝试评估它会产生一个NameError。然而,不知何故,在这个操作之后,baz 被定义了,并且其值为nil。看起来,值nil 被分配给变量baz,即使没有人(明确地)要求它。这种行为是可取的,是否存在潜在的语言原因?

解释这种行为和其他类似混淆结构的规则是什么,例如:

irb:04> true if foo            # => NameError
irb:05> foo                    # => NameError; name still undefined
irb:06> foo = (true if foo)    # => nil
irb:07> foo                    # => nil; name defined as nil
irb:08> true || i = 0 || j = 2 # => i and j are nil; || appears nonlazy
irb:09> raise || quux = 1      # => RuntimeError, quux is nil

【问题讨论】:

标签: ruby jruby


【解决方案1】:

我不知道它是否可取,但它来自 Ruby 如何解析代码。每当您有一段分配局部变量的代码时,即使未评估该段代码,也会为该局部变量分配nil。在您的代码第 2 行:

baz || baz = 0

第一个 baz 返回错误,因为没有分配这样的变量。因此,紧随其后的赋值 baz = 0未评估,但它已解析,因此在接下来的上下文中,创建了一个局部变量 baz,并且初始化为nil

对于您的第二个代码块,footrue if foofoo 期间未分配。之后,foo = (true if foo) 分配给 foo,因此即使在分配 foo 之前评估 (true if foo),也不会在该行中引发错误。

【讨论】:

  • 必须删除我的评论,因为你已经修复了你的答案;-) 现在它是正确的,分配给 baz 是 not 但只要 Ruby parser 检测到一个分配,它为其分配一个空间并设置为nil
  • @DavidUnric 你可能对我之前的回答有话要说,但现在,我认为你的评论没有增加我的回答之外的任何信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多