Worlogog::Restart - Lisp-style dynamic restarts


  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


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.


The following functions are available:

invoke RESTART

Invokes RESTART, passing it ARGUMENTS (if any) in @_. Returns whatever RESTART returns (provided it returns normally, which restarts established by case never do).

RESTART can be either a restart object (such as those returned by find or compute) or a restart name (a string). Names are looked up dynamically by searching outwards through all handlers established by bind or case. If no matching restart is found, this is an error and invoke dies.


Executes BLOCK with the restarts specified by HASHREF, which maps restart names (strings) to handlers (subroutine references). Returns whatever BLOCK returns.


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 invoke is used to return from case).

Unlike bind, the restarts it establishes always unwind the stack first before running and thus ultimately return from case itself, not from invoke. That is, a restart established by case will implicitly return from all subroutines between case and invoke, then execute the handler body specified in HASHREF, then return from case.


Finds the restart that would be called by invoke at this point. Returns a restart object representing the restart or undef if no corresponding restart is active. RESTART must be a name (string).

Restart objects returned by find have the following methods:


Returns the name of the restart.


Returns the subroutine reference of the restart handler.


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
    } {
      foo => sub { $_[0] + 2 },
  } {
    foo => sub { $_[0] * 3 },

This module uses Exporter::Tiny, so you can rename the imported functions at use time.


Exporter::Tiny, Return::MultiLevel


Lukas Mai, <l.mai at>


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 for more information.