NAME
Worlogog::Restart - Lisp-style dynamic restarts
SYNOPSIS
use Worlogog::Restart -all => { -prefix => 'restart_' };
my $x = restart_case {
restart_invoke 'foo', 21;
die; # not reached
} {
foo => sub {
return $_[0] * 2;
},
};
print "$x\n"; # 42
my $y = restart_bind {
my $x = restart_invoke 'bar', 20;
return $x + 2;
} {
bar => sub {
return $_[0] * 2;
},
};
print "$y\n"; # 42
DESCRIPTION
This module provides dynamic restarts similar to those found in Common Lisp. A restart is a bit like an exception handler or a dynamically scoped function. It can be invoked (by name) from any subroutine call depth as long as the restart is active.
Functions
The following functions are available:
- invoke RESTART
- invoke RESTART, ARGUMENTS
-
Invokes RESTART, passing it ARGUMENTS (if any) in
@_. Returns whatever RESTART returns (provided it returns normally, which restarts established bycasenever do).RESTART can be either a restart object (such as those returned by
findorcompute) or a restart name (a string). Names are looked up dynamically by searching outwards through all handlers established bybindorcase. If no matching restart is found, this is an error andinvokedies. - bind BLOCK HASHREF
-
Executes BLOCK with the restarts specified by HASHREF, which maps restart names (strings) to handlers (subroutine references). Returns whatever BLOCK returns.
- case BLOCK HASHREF
-
Executes BLOCK with the restarts specified by HASHREF, which maps restarts names (strings) to handlers (subroutine references). Returns whatever BLOCK returns (or what the corresponding restart returns if
invokeis used to return fromcase).Unlike
bind, the restarts it establishes always unwind the stack first before running and thus ultimately return fromcaseitself, not frominvoke. That is, a restart established bycasewill implicitly return from all subroutines betweencaseandinvoke, then execute the handler body specified in HASHREF, then return fromcase. - find RESTART
-
Finds the restart that would be called by
invokeat this point. Returns a restart object representing the restart orundefif no corresponding restart is active. RESTART must be a name (string).Restart objects returned by
findhave the following methods: - compute
-
Searches outwards and returns a list of restart objects representing all currently active restarts. The innermost restarts will be listed first.
The returned list may contain restarts that you can't normally invoke because they're shadowed by a more recent restart with the same name:
# prints "9" because the innermost 'foo' is listed first print bind { bind { my @restarts = compute; # # $restarts[0]->name = 'foo' # $restarts[0]->code = sub { $_[0] + 2 } # # $restarts[1]->name = 'foo' # $restarts[1]->code = sub { $_[0] * 3 } my $x = 1; $x = invoke($_, $x) for @restarts; # $x = $x + 2 # $x = $x * 3 $x } { foo => sub { $_[0] + 2 }, }; } { foo => sub { $_[0] * 3 }, };
This module uses Exporter::Tiny, so you can rename the imported functions at use time.
SEE ALSO
Exporter::Tiny, Return::MultiLevel
AUTHOR
Lukas Mai, <l.mai at web.de>
COPYRIGHT & LICENSE
Copyright 2013, 2014 Lukas Mai.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.