rescue, ensure and else with blocks. However the following examples shows, that variables are unexpectedly handled:%w(foo bar).each do |x|
ensure
p x # => ERROR: undefined local variable or method 'x'
end
This should be equivalent to:
%w(foo bar).each do |x|
begin
ensure
p x
end
end
Which compiles without errors. Block arguments are initialized in every block run, they are before the implicit begin and should be visible in rescue, ensure and else branches.
Second example:
%w(foo bar).each do |x|
foo = x
ensure
p foo.upcase # => ERROR: undefined method 'foo'
end
Which should be equivalent to:
%w(foo bar).each do |x|
begin
foo = x
ensure
p foo.upcase # => ERROR: undefined method 'upcase' for Nil (compile-time type is (String | Nil))
end
end
The variable foo should be visible in rescue, ensure and else branches but be nilable there, just like in the expressive variant.
/cc @MakeNowJust
Good catch!
Most helpful comment
Good catch!