未执行的行(被“if false”阻止)仍会影响结果[重复]

问题描述 投票:0回答:1

我想使用经典的|| =重新赋值(cf Set Ruby variable if it is not already defined)和ActiveInteraction,就像在https://github.com/AaronLasseigne/active_interaction/issues/395中一样

然而,通过在ActiveInteraction中测试不同的语法,我偶然发现了一个甚至在vanilly Ruby中发生的更奇特的问题。

未执行的行(由if false阻止)仍然可以对其余代码产生重大影响:

class A
  attr_accessor :a

  def run
    (puts defined? a; a) if true
  end

  def run2
    (puts 'change a'; a = 0) if false
    puts defined? a
    a
  end

end

x = A.new
x.run  # "method"; nil
x.run2 # "local-variable"; nil
x.a = 5
x.run # "method"; 5
x.run2 # "local-variable"; nil

任何人都可以解释这是一个错误还是一个功能?如果一个功能:怎么来的?这看起来很奇怪。

编辑:感谢@Sergio Tulentsev的回答,我设法发现我的问题几乎与Ruby instance method & conditional local variable assignment with same name重复,标题名称不同。

ruby
1个回答
3
投票

[这是]一个错误还是一个功能?

都不是。这是......特殊性。当解析器在代码中看到对局部变量的赋值时,会发生这种情况,并将该名称添加到作用域(从该行开始,可能会影响其他名称,如此处的方法)。使用nil的默认值。如果从未执行实际赋值,则新的局部变量仍在范围内,仍然计算为nil

这在https://docs.ruby-lang.org/en/2.5.0/syntax/assignment_rdoc.html#label-Local+Variables+and+Methods中有记载。

© www.soinside.com 2019 - 2024. All rights reserved.