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