我正在尝试处理 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/