Else inside rescue is useless?

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]

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?

my ruby version is
ruby 1.8.4 (2005-12-24) [i686-linux]

exactly, the else is in the rescue which means an exception has been thrown. if it doesn;t match any of the exceptions you've declared as being important to catching, and you include an else, the else wiill catch what you don;t want.

no?!

cap <capitain@gmail.com> 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]

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?

my ruby version is
ruby 1.8.4 (2005-12-24) [i686-linux]

---------------------------------
The all-new Yahoo! Mail goes wherever you go - free your email address from your Internet provider.

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

···

On 11.12.2006 13:17, cap wrote:

From the Rubinius test suite:
    @count = 1
    begin
      p @count
      raise ArgumentError, 'just kidding' unless @count > 3
    rescue Exception => e
      @count += 1
      retry
    else
      p 7
    ensure
      p 8
    end

this prints:
1
2
3
4
7
8

'else' only runs if no exception was raised.

···

On 12/11/06, cap <capitain@gmail.com> 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]

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?

my ruby version is
ruby 1.8.4 (2005-12-24) [i686-linux]

Hi --

exactly, the else is in the rescue which means an exception has been
thrown. if it doesn;t match any of the exceptions you've declared as
being important to catching, and you include an else, the else wiill
catch what you don;t want.

no?!

No; I think what you need is just a blank 'rescue', not else:

   begin
     puts "do something"
     raise ZeroDivisionError
   rescue NameError
     puts "name error #{$!}"
   rescue
     puts "else #{$!}"
   end

Output:

   do something
   else ZeroDivisionError

An else clause will run if there's no exception at all.

I don't have my Ruby Way on me but if it says else I think it should
say rescue.

David

···

On Mon, 11 Dec 2006, Anthony Gardner wrote:

--
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

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.

I would be horrified if the <else> were executed after a <return> -- <else> is not <ensure>. The Pickaxe book should be probably say: "If an else clause is present, its body is executed if no exceptions were raised and no exit was made in _code_ ." In fact, I just submitted an erratum to this effect on the Pragmatic Programmer site.

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.

Also from Pickaxe: "Exceptions raised during the execution of the else clause are not captured by rescue clauses in the same block as the else." That seems to be a semantic difference.

Regards, Morton

···

On Dec 11, 2006, at 8:55 AM, Robert Klemme wrote:

Why would you expect the else clause to be executed if a return is executed? That seems counter-intuitive to me.

Cheers

Dave

···

On Dec 11, 2006, at 7:55 AM, Robert Klemme wrote:

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.

If I'm understanding you correctly, there is a difference between:

  begin
    f
    g
  rescue E
  end

and

  begin
    f
  rescue E
  else
    g
  end

and that is that any E's raised in #g won't be rescued in the latter.

···

On 12/12/06, Robert Klemme <shortcutter@googlemail.com> wrote:

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.

From the Rubinius test suite:

  @count = 1
  begin
    p @count
    raise ArgumentError, 'just kidding' unless @count > 3
  rescue Exception => e
    @count += 1
    retry
  else
    p 7
  ensure
    p 8
  end

[...]

'else' only runs if no exception was raised.

Yes, else only runs if no exception was raised; and it will run BEFORE the ensure block. BUT unlike code in the main code block (begin..rescue) it CAN raise unchecked exceptions.

Benedikt

   ALLIANCE, n. In international politics, the union of two thieves who
     have their hands so deeply inserted in each other's pockets that
     they cannot separately plunder a third.
       (Ambrose Bierce, The Devil's Dictionary)

···

On Tue, 12 Dec 2006, Wilson Bilkovich wrote:

yeha, yeah, yeah. my mistake.

am new to ruby but now remember that the else is only run if no exceptions occur in the main body. bit of revision there :wink:

dblack@wobblini.net wrote: Hi --

exactly, the else is in the rescue which means an exception has been
thrown. if it doesn;t match any of the exceptions you've declared as
being important to catching, and you include an else, the else wiill
catch what you don;t want.

no?!

No; I think what you need is just a blank 'rescue', not else:

   begin
     puts "do something"
     raise ZeroDivisionError
   rescue NameError
     puts "name error #{$!}"
   rescue
     puts "else #{$!}"
   end

Output:

   do something
   else ZeroDivisionError

An else clause will run if there's no exception at all.

I don't have my Ruby Way on me but if it says else I think it should
say rescue.

David

···

On Mon, 11 Dec 2006, Anthony Gardner wrote:

--
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

---------------------------------
The all-new Yahoo! Mail goes wherever you go - free your email address from your Internet provider.

I have low expectations with regard to the "else" clause but the book clearly states that it is executed if there was no exception - that includes the case where the block is left via a "return". Behavior and description simply are not in sync, that's my point.

I can't remember ever having used this type of "else" clause so far so I am pretty nonreligious about it. Although I can imagine a situation where I would want to make sure some cleanup code is executed only when there was no error in the block - and this includes leaving via "return". Of course you can argue that leaving via "return" is a non standard way to leave the block... As I said, I am pretty relaxed here. I just think this needs some clarification - either way or the other.

Kind regards

  robert

···

On 12.12.2006 00:15, Dave Thomas wrote:

On Dec 11, 2006, at 7:55 AM, Robert Klemme wrote:

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.

Why would you expect the else clause to be executed if a return is executed? That seems counter-intuitive to me.

Do you feel like that's an implementation quirk of Ruby, or something
deliberate?
In other words, this code..

@count = 0
begin
  @count += 1
  raise RuntimeError.new("Ha Ha!") if @count == 1
rescue Exception
  puts "hello from rescue"
  retry
else
  puts "else"
  raise RuntimeError.new("Boom") if @count == 2
end

Is it part of ruby's 'spec' that the 'rescue' block only be executed
once, in the above code?

···

On 12/12/06, Benedikt Heinen <ruby@ml.icemark.net> wrote:

On Tue, 12 Dec 2006, Wilson Bilkovich wrote:
>> From the Rubinius test suite:
> @count = 1
> begin
> p @count
> raise ArgumentError, 'just kidding' unless @count > 3
> rescue Exception => e
> @count += 1
> retry
> else
> p 7
> ensure
> p 8
> end

[...]

> 'else' only runs if no exception was raised.

Yes, else only runs if no exception was raised; and it will run BEFORE the
ensure block. BUT unlike code in the main code block (begin..rescue) it
CAN raise unchecked exceptions.

>
>> 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.
>
> Why would you expect the else clause to be executed if a return is
> executed? That seems counter-intuitive to me.

I have low expectations with regard to the "else" clause but the book
clearly states that it is executed if there was no exception - that
includes the case where the block is left via a "return". Behavior and
description simply are not in sync, that's my point.

I can't remember ever having used this type of "else" clause so far so I
am pretty nonreligious about it. Although I can imagine a situation
where I would want to make sure some cleanup code is executed only when
there was no error in the block - and this includes leaving via
"return".

and that is what ensure is for, right?
I guess the book is wrong and Matz is right ;), well my POV

  Of course you can argue that leaving via "return" is a non

standard way to leave the block... As I said, I am pretty relaxed here.
  I just think this needs some clarification - either way or the other.

Kind regards

        robert

Likewise

···

On 12/12/06, Robert Klemme <shortcutter@googlemail.com> wrote:

On 12.12.2006 00:15, Dave Thomas wrote:
> On Dec 11, 2006, at 7:55 AM, Robert Klemme wrote:

--
"The real romance is out ahead and yet to come. The computer revolution
hasn't started yet. Don't be misled by the enormous flow of money into bad
defacto standards for unsophisticated buyers using poor adaptations of
incomplete ideas."

- Alan Kay

Interesting: I'd honestly never have thought of that interpretation. I guess in my mind, the semantics of return take precedence over most other semantics, and I explicitly note the times where that's not the case. Thanks for pointing out an alternative.

Do you feel I should also document the other places when a return could be issued? For example, in the description of a while loop, I say "executes body zero or more times as long as boolean-expression is true." Should I add "or a return is executed or an exception is thrown" to this and similar descriptions?

I kind of feel that this would clutter the descriptions, and that most readers would make the assumption that return and exceptions would break the flow. Is that an incorrect assumption?

Regards

Dave

···

On Dec 12, 2006, at 4:10 AM, Robert Klemme wrote:

I have low expectations with regard to the "else" clause but the book clearly states that it is executed if there was no exception - that includes the case where the block is left via a "return". Behavior and description simply are not in sync, that's my point.

> 'else' only runs if no exception was raised.

Yes, else only runs if no exception was raised; and it will run BEFORE the
ensure block. BUT unlike code in the main code block (begin..rescue) it
CAN raise unchecked exceptions.

Do you feel like that's an implementation quirk of Ruby, or something
deliberate?
In other words, this code..

@count = 0
begin
@count += 1
raise RuntimeError.new("Ha Ha!") if @count == 1
rescue Exception
puts "hello from rescue"
retry
else
puts "else"
raise RuntimeError.new("Boom") if @count == 2
end

Is it part of ruby's 'spec' that the 'rescue' block only be executed
once, in the above code?

It sounds like it is deliberate - otherwise, why introducing the else block at all? That's the only thing that else does.

Also, when you say "rescue block only be executed once in the above code", if you took the first raise ("Ha Ha!") away - it would not trigger the rescue at all. This is apparently, why 'else' is positioned AFTER 'rescue' in the execution order. Once you're past the rescue block, there is no rescue to jump back to. i.e. if you want to rescue from an exception in the else block, you'd need to do it in a separate begin..rescue..end block wrapping around the begin..rescue..else..end construct you are using.

Benedikt

   ALLIANCE, n. In international politics, the union of two thieves who
     have their hands so deeply inserted in each other's pockets that
     they cannot separately plunder a third.
       (Ambrose Bierce, The Devil's Dictionary)

> I have low expectations with regard to the "else" clause but the
> book clearly states that it is executed if there was no exception -
> that includes the case where the block is left via a "return".
> Behavior and description simply are not in sync, that's my point.

Interesting: I'd honestly never have thought of that interpretation.
I guess in my mind, the semantics of return take precedence over most
other semantics, and I explicitly note the times where that's not the
case. Thanks for pointing out an alternative.

Do you feel I should also document the other places when a return
could be issued? For example, in the description of a while loop, I
say "executes body zero or more times as long as boolean-expression
is true." Should I add "or a return is executed or an exception is
thrown" to this and similar descriptions?

I kind of feel that this would clutter the descriptions, and that
most readers would make the assumption that return and exceptions
would break the flow. Is that an incorrect assumption?

Maybe the assumption is wrong in some, maybe even many cases, but I believe
you should keep this one as simple as possible, at this very point.
While explaining "while" you might not want to confuse newbies, and more
advanced readers might satisfy your assumption more likely anyway.

The structurally more complicated stuff like raise, ensure and do not forget
nonlocal jumps (aka continuations) should be explained elsewhere and I
believe it is exactly at that elsewhere point where one might explain the
impacts on the more basic constructs.

This is just a great piece of work and I think it is about perfect as it is
now, well maybe I should read it after all :wink:

Regards

···

On 12/12/06, Dave Thomas <dave@pragprog.com> wrote:

On Dec 12, 2006, at 4:10 AM, Robert Klemme wrote:

Dave

Robert (D not K)

--
"The real romance is out ahead and yet to come. The computer revolution
hasn't started yet. Don't be misled by the enormous flow of money into bad
defacto standards for unsophisticated buyers using poor adaptations of
incomplete ideas."

- Alan Kay

I have low expectations with regard to the "else" clause but the book clearly states that it is executed if there was no exception - that includes the case where the block is left via a "return". Behavior and description simply are not in sync, that's my point.

Interesting: I'd honestly never have thought of that interpretation. I guess in my mind, the semantics of return take precedence over most other semantics, and I explicitly note the times where that's not the case. Thanks for pointing out an alternative.

Dave, you're welcome! I was probably in formal mode when reading that, although I believe the situation here is a tad different from the "while" loop case:

Do you feel I should also document the other places when a return could be issued? For example, in the description of a while loop, I say "executes body zero or more times as long as boolean-expression is true." Should I add "or a return is executed or an exception is thrown" to this and similar descriptions?

Maybe just "... or the body of the loop is left via other control flow statements". You could even add a footnote which enumerates them. :slight_smile:

I kind of feel that this would clutter the descriptions, and that most readers would make the assumption that return and exceptions would break the flow. Is that an incorrect assumption?

I agree about cluttering and I think a change is not needed in this cases - in other words, I believe it's not an incorrect assumption. :slight_smile:

I think the case with "else" clause after "rescue" clauses is a bit different because control flow is not explicit like with loops. It is immediately clear that "break", "return", "raise" and "throw" will instantly leave the loop (is it?). However, with "rescue - else" we are talking about less explicit control flow and so maybe a more explicit description is helpful here.

As I said, it's probably a corner case and I have no idea how often this "else" is actually used in applications. I for my part cannot remember ever having used it - apart from the research for this thread.

It's a totally different question whether the behavior of the interpreter should change so code in "else" clause is executed even for a "return". There might be arguments in favor and against it. Maybe Matz can shed some light about the reasoning why it is the way it is.

Kind regards

  robert

···

On 12.12.2006 14:31, Dave Thomas wrote:

On Dec 12, 2006, at 4:10 AM, Robert Klemme wrote:

Hi --

I have low expectations with regard to the "else" clause but the book clearly states that it is executed if there was no exception - that includes the case where the block is left via a "return". Behavior and description simply are not in sync, that's my point.

Interesting: I'd honestly never have thought of that interpretation. I guess in my mind, the semantics of return take precedence over most other semantics, and I explicitly note the times where that's not the case. Thanks for pointing out an alternative.

Do you feel I should also document the other places when a return could be issued? For example, in the description of a while loop, I say "executes body zero or more times as long as boolean-expression is true." Should I add "or a return is executed or an exception is thrown" to this and similar descriptions?

I kind of feel that this would clutter the descriptions, and that most readers would make the assumption that return and exceptions would break the flow. Is that an incorrect assumption?

No, I think it's correct. I consider "executes body" to expand
automatically to "executes body unless execution is stopped, which can
always happen in various ways no matter what else is going on".

I think the reason the question arose in the particular case of
begin/rescue/else/ensure... is that it involves the role of what to me
is a somewhat elusive clause (the else) right in the middle of a
construct where the control flow is already relatively complex.

David

···

On Tue, 12 Dec 2006, Dave Thomas wrote:

On Dec 12, 2006, at 4:10 AM, Robert Klemme wrote:

--
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

Robert Klemme wrote:

I have low expectations with regard to the "else" clause but the book clearly states that it is executed if there was no exception - that includes the case where the block is left via a "return". Behavior and description simply are not in sync, that's my point.

Dave Thomas replied:

Interesting: I'd honestly never have thought of that interpretation.

[...]

Do you feel I should also document the other places when a return could be issued? For example, in the description of a while loop, I say "executes body zero or more times as long as boolean-expression is true." Should I add "or a return is executed or an exception is thrown" to this and similar descriptions?

I kind of feel that this would clutter the descriptions, and that most readers would make the assumption that return and exceptions would break the flow. Is that an incorrect assumption?

I think detailing every condition under which else would not get called is overdoing it a bit.

Instead of listing the conditions under which the else might not be reached; how about instead of writing "The body of an else clause is executed only if no exceptions are raised by the main body of code." You'd write "The body of an else clause is executed only if the end of the main body of code is reached without causing any exceptions". This to me would sound more clear - a return statement in the main block would prevent the end of the main body of code to be reached.

So, the difference is just that I can use the else block to insert code that will run before the ensure (in your book example before the ensured file.close) but outside of the rescue blocks (i.e. code in the else block CAN throw an exception which will not be handled in the current begin/rescue block... (Whether this is useful or not, is another issue)...

         def testme()
           begin
             begin
               puts "foo"
               #return(1);
         puts "raising error"
               puts "bar"
             rescue
               puts "inner rescue block"
             else
               raise ArgumentError.new("blah");
             ensure
               puts "ensured"
             end

           rescue
             puts "outer rescue block"
           end
         end

         testme();

will print

   foo
   bar
   raising error
   ensured
   outer rescue block

If I were to uncomment the return(1), it would print

   foo
   ensured

Benedikt

   ALLIANCE, n. In international politics, the union of two thieves who
     have their hands so deeply inserted in each other's pockets that
     they cannot separately plunder a third.
       (Ambrose Bierce, The Devil's Dictionary)

Hi --

···

On Tue, 12 Dec 2006, Robert Klemme wrote:

On 12.12.2006 14:31, Dave Thomas wrote:

On Dec 12, 2006, at 4:10 AM, Robert Klemme wrote:

I have low expectations with regard to the "else" clause but the book clearly states that it is executed if there was no exception - that includes the case where the block is left via a "return". Behavior and description simply are not in sync, that's my point.

Interesting: I'd honestly never have thought of that interpretation. I guess in my mind, the semantics of return take precedence over most other semantics, and I explicitly note the times where that's not the case. Thanks for pointing out an alternative.

Dave, you're welcome! I was probably in formal mode when reading that, although I believe the situation here is a tad different from the "while" loop case:

Do you feel I should also document the other places when a return could be issued? For example, in the description of a while loop, I say "executes body zero or more times as long as boolean-expression is true." Should I add "or a return is executed or an exception is thrown" to this and similar descriptions?

Maybe just "... or the body of the loop is left via other control flow statements". You could even add a footnote which enumerates them. :slight_smile:

I don't think that's needed. Executing a body of code means executing
all the instructions in it, and it's already known that the
instruction set includes things that affect flow control. So unless
those things are specifically excluded in a given context, I would
assume they are available.

David

--
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)