Brian Candler <b.candler / pobox.com> wrote/schrieb <652eb79164d21c8ee8f6343eda170495 / ruby-forum.com>:

> So I think the solution is easy: use two different symbols, e.g. 
> catch(:next_document) in document, and catch(:next_multiline_tail) in 
> multiline_tail.

That's not enough. Now recursion comes into place: multiline_tail can
call itselve via the method multiline. Then there's the same nesting
problem, but renaming doesn't help, because inner and outer
catch/throw pairs would be all renamed at the same time to the same
new symbol.

> This works for the trivial document you provided. You might want to try 
> a more substantial example though :-)

Of course I want to try:

This input line
(())
should result in an empty output line.

Or even simpler, this input line
(()
should result in that output line:
(

> Perl has statement labels for this:
>
>   OUTER:
>   while(1) {
>     ...
>     next OUTER
>   }

Yes, I remember the labeled loops in Perl. It's a proper lexicographic
label. As a reader of the source code you don't have to track the
dynamic behaviour to find out where the jump will go to.

> but I don't think Ruby has a direct equivalent.

which seems to be a pitty. At a first look catch/throw pairs seem to
be equivalent, but as soon as two conflicting functions or -- even
worse -- recursions can happen, it turns out to be too week as a
direct replacement.

> P.S. If I understand your code right, I think you can simplify multiline 
> to:
> [...]
> does is to relay the call back to the original block, so why not just 
> yield to the original block directly? You were using the 'return' 
> statement too, which has special use within a block, but I think it may 
> not be needed here.

Thanks for your hints.

Regards
  Thomas