On 11.12.2006 13:17, cap wrote:
> http://www.awprofessional.com/bookstore/product.asp?isbn=0672328844&rl=1
> 
> The "The ruby way" book said
> 
> [quote]
> In the event that error types are specified, it may be that an
> exception does not match any of these types. For that situation, we are
> allowed to use an else clause after all the rescue clauses.
> 
> begin
>   # 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).

> but actually, I found the "else" clause is only executed when there is
> no exception been thrown,such as :
> 
> -------------------------
> begin
>     puts "do something"
> rescue NameError
>     puts "name error  #{$!}"
> else
>     puts "else  #{$!}"
> end
> --------------------------
> 
> the result is
> 
> -------------------
> do something
> else
> ------------------
> 
> so the "else" clause is useless because we can simply put the content
> 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