Итак, у нас есть код:
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
определено в блоке обеспечения? (кстати, он определен как ноль)
ОБНОВЛЕНИЕ: Спасибо @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 method
a для main:Object`. - person Cary Swoveland   schedule 31.03.2015