【发布时间】:2015-06-04 23:43:54
【问题描述】:
所以,我们有代码:
class Foo
def bar
puts "Before existent: #{(defined? some_variable)}"
puts "Before not_existent: #{(defined? nonexistent_variable)}"
raise "error"
some_variable = 42
rescue
puts "exception"
ensure
puts "Ensure existent: #{(defined? some_variable)}"
puts "Ensure not_existent: #{(defined? nonexistent_variable)}"
end
end
然后从 irb 调用它:
> Foo.new.bar
而且,那将返回:
Before existent:
Before not_existent:
exception
Ensure existent: local-variable
Ensure not_existent:
=> nil
现在是问题 - 为什么?我们在定义some_variable 之前提出了异常之前。
为什么它会这样工作?为什么 some_variable 在确保块中定义? (顺便说一句,它定义为 nil)
更新: 感谢@Max 的回答,但是如果我们更改代码以使用实例变量:
class Foo
def bar
puts "Before existent: #{(defined? @some_variable)}"
puts "Before not_existent: #{(defined? @nonexistent_variable)}"
raise "error"
@some_variable = 42
ensure
puts "Ensure existent: #{(defined? @some_variable)}"
puts "Ensure not_existent: #{(defined? @nonexistent_variable)}"
end
end
它按预期工作:
Before existent:
Before not_existent:
Ensure existent:
Ensure not_existent:
为什么?
【问题讨论】:
-
对未定义的实例(和全局)变量的引用与对未定义的局部(和类)变量的处理方式不同。例如,
puts @a #=> nil,而puts a #NameError: undefined local variable or methoda' 代表 main:Object`。
标签: ruby exception behavior defined