ruby - 了解 Ruby 中的作用域

标签 ruby recursion scope

我正在尝试处理 Ruby 中一个非常奇怪的(至少对我而言)情况。我的代码如下:

class ScopeTest
  attr_accessor :flag

  def flagtest
    puts "SELF: " + self.flag.to_s
    puts "INST: " + flag.to_s
    if flag == 1
      flag = 0
      puts "SELF: " + self.flag.to_s
      puts "INST: " + flag.to_s
      self.flag = 0
      puts "SELF: " + self.flag.to_s
      puts "INST: " + flag.to_s
      flagtest
    else
      puts "SELF: " + self.flag.to_s
      puts "INST: " + flag.to_s
    end
  end
end

st = ScopeTest.new
st.flag = 1
st.flagtest

输出如下:

SELF: 1
INST: 1
SELF: 1
INST: 0
SELF: 0
INST: 0
SELF: 0
INST: 0
SELF: 0
INST: 

奇怪的是 flag 变量是 nil 我最后一次打印它(在 else 内)但是 0 就在那之前(在 flagtest 方法中的 if...else 之前)?

当我删除几行代码时,一切似乎都恢复正常,如下代码所示:

class ScopeTest
  attr_accessor :flag

  def flagtest
    puts "SELF: " + self.flag.to_s
    puts "INST: " + flag.to_s
    if flag == 1
      self.flag = 0
      puts "SELF: " + self.flag.to_s
      puts "INST: " + flag.to_s
      flagtest
    else
      puts "SELF: " + self.flag.to_s
      puts "INST: " + flag.to_s
    end
  end
end

st = ScopeTest.new
st.flag = 1
st.flagtest

给出以下输出:

SELF: 1
INST: 1
SELF: 0
INST: 0
SELF: 0
INST: 0
SELF: 0
INST: 0

关于发生了什么以及为什么发生的任何线索?

最佳答案

这是因为您对局部变量进行了赋值,flag = 0。 IIRC,局部变量是在解析时创建的,并且在方法范围内。默认情况下,它们使用 nil 进行初始化。因此,在您的 then 子句中,您在访问它之前为其分配了一个值。但是当您重新进入该方法时,您会转到 else 子句并且 flag 未初始化(即 nil)。

class ScopeTest
  attr_accessor :flag

  def flagtest
    # if you comment this line, the method will output 1, 1
    # if you don't comment, it will output 1, nil, because the assignment to local variable was never done.
    #   but local var itself was created.
    flag = 3 if false

    puts self.flag.inspect
    puts flag.inspect
  end
end

st = ScopeTest.new
st.flag = 1
st.flagtest
# >> 1
# >> nil

关于ruby - 了解 Ruby 中的作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18576575/

相关文章:

ruby - StringIO 实例改变原始字符串

python - 不同的 YAML 数组表示

ruby-on-rails - Rails Controller 操作是否隐式定义事务绑定(bind)?

java - 给定斐波那契递归函数创建内存算法

function - 在 Shell 脚本中将变量作用域到函数的 POSIX 兼容方式

javascript - 函数 if 语句内使用的全局变量似乎是空白 JavaScript

ruby-on-rails - 如何通过 Assets 管道加载css.erb文件

c - 使用 fork() 运行太多次来遍历目录的递归函数

JavaScript,只能使用下划线 _ 访问属性

python - 异常处理的范围规则是什么?