On 11.12.2006 13:17, cap wrote:
Error-prone code…
rescue Type1
…
rescue Type2
…
else
Other exceptions…
end
[/quote]
This is plain wrong - at least in 1.8.5. The Pickaxe says the “else”
clause is executed if there was no exception. To catch any exception
you would have to replace the “else” with “rescue Exception => e” as
David indicated. However, there’s a glitch (read on).
end
of “else” caluse to the last line in the “begin” block before the first
“rescue”
Am I wrong or the book is wrong?
I think the book is wrong - and there is also a difference between the
Pickaxe and the interpreter implementation (unfortunately). Try this
code:
def foo(x)
begin
puts “x=#{x}”
case x
when 0
puts "returning"
return
when 1
raise "Some error"
when 2
raise NameError, "wrong name"
when 3
break "broken"
else
puts "do something"
end
puts "unsafe else"
rescue NameError
puts “name error: #{$!}”
else
puts “else”
ensure
puts “leaving!”
end
end
5.times do |i|
begin
foo i
rescue Exception => e
puts “Exception: #{e}”
end
end
With my 1.8.5 I see:
x=0
returning
leaving!
x=1
leaving!
Exception: Some error
x=2
name error: wrong name
leaving!
x=3
leaving!
Exception: unexpected break
x=4
do something
unsafe else
else
leaving!
What bugs me is that the “else” clause is not executed if it is left via
a “return”. Taking the Pickaxe 2nd edition pg. 362 literally (“If an
else clause is present, its body is executed if no exceptions were
raised in code.”) it would have to be executed in that case, too. So,
if the interpreter would behave as stated in the book, there was
actually a difference between the code at the end of the block and the
code inside the else clause.
Even in the current situation (where there seems to be no semantically
difference) putting code into the else clause instead of the end of the
block might have an advantage documentation wise.
Matz, can you clarify whether this is a bug in the interpreter or
whether the Pickaxe is wrong (or incomplete) here?
Kind regards
robert