Thank you all very much.
This has been a big help.
This is what I was looking for.

--Alex

On 5/31/07, Bob Rogers <[EMAIL PROTECTED]> wrote:
>
>    From: Gyepi SAM <[EMAIL PROTECTED]>
>    Date: Thu, 31 May 2007 15:22:32 -0400
>
>    Hi Alex,
>
>    What you're asking is possible, especially since you only asked for
>    quick and easy and said nothing about elegant ;)
>
>    The situation you describe is known as a 'condition' in Lisp, which
> allows
>    you to define the catch and handle exceptional conditions in your
> program,
>    including *restarting* the offending piece of code (presumably after
>    changing program state to prevent looping) . . .
>
> Well, the notion of "restarting" also includes such things as "skip the
> operation", "suppress the warning", etc.  The "try the same thing again"
> restarts are mostly intended for use by interactive debuggers, where
> looping is not a problem.
>
>    The thing I find most impressive about the Common Lisp condition
> system is that it allows the signalling (detection) of an error, the
> provision of restart/retry code, and the decision of which restart, if
> any, to take (handling) to be implemented by three different people
> writing at different times and communicating only through software
> documentation.  See [1] for a general overview of Lisp conditions.
>
>    However, since Alex seems to have control over all of the code
> involved, there is a simpler approach.  The following version of your
> "Plort" example uses a callback [2] that closes over the "done:" label
> instead of using eval/die:
>
>         #! /usr/bin/perl -w
>
>         use strict;
>         use warnings;
>
>         use vars qw($callback);
>
>         sub Plort {
>             print "in Plort, calling Foo()\n";
>
>             local $callback = sub {
>                 print "In callback.\n";
>                 goto DONE;
>             };
>
>             Foo();
>
>             print "in Plort, returned from Foo() [not]\n";
>
>           DONE:
>             print "in Plort, done with Foo()\n";
>         }
>
>         sub Foo {
>             print "in Foo, calling Error()\n";
>             Error();
>             print "in Foo, back from Error, but you'll never see this
> line";
>         }
>
>         sub Error {
>             print "in Error, invoking callback.\n";
>             $callback->();
>         }
>
>         Plort();
>
> Note that this script works in Perl 5.8.1, but not in 5.6, where the
> lexical sub is not allowed to "goto" a label that is in the containing
> lexical scope.  I don't know exactly when this feature was added/bug was
> fixed.
>
> Running this produces the following output:
>
>         [EMAIL PROTECTED]> perl-condition.pl
>         in Plort, calling Foo()
>         in Foo, calling Error()
>         in Error, invoking callback.
>         In callback.
>         in Plort, done with Foo()
>         [EMAIL PROTECTED]>
>
> Two advantages of this technique spring to mind:
>
>    1.  It is transparent to eval/die, so it doesn't muck up other error
> processing, an unfortunate weakness of resignalling [3].  In particular,
> introducing an eval to the internals of Foo can never intercept the
> nonlocal exit performed by the callback.
>
>    2.  The notion of how many levels to exit (the "parent/grandparent"
> thing) doesn't have to be hardwired.  The Error sub can be called at
> arbitrary points within the implementation of Foo, at different levels,
> and will still do the right thing in each case.
>
>    HTH,
>
>                                         -- Bob Rogers
>                                            http://rgrjr.dyndns.org/
>
> [1]  Kent M. Pitman, "Condition Handling in the Lisp Language Family",
>      http://www.nhplace.com/kent/Papers/Condition-Handling-2001.html
>
> [2]  Need I say what else I could have called it?  ;-}
>
> [3]  Perl 6 will do this better.
>
 
_______________________________________________
Boston-pm mailing list
[email protected]
http://mail.pm.org/mailman/listinfo/boston-pm

Reply via email to