The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


Return::MultiLevel - Return across multiple call levels


version 0.08


  use Return::MultiLevel qw(with_return);

  sub inner {
    my ($f) = @_;
    $f->(42);  # implicitly return from 'with_return' below
    print "You don't see this\n";

  sub outer {
    my ($f) = @_;
    print "You don't see this either\n";

  my $result = with_return {
    my ($return) = @_;
    die "Not reached";
  print $result, "\n";  # 42


This module provides a way to return immediately from a deeply nested call stack. This is similar to exceptions, but exceptions don't stop automatically at a target frame (and they can be caught by intermediate stack frames using eval). In other words, this is more like setjmp(3)/longjmp(3) than die.

Another way to think about it is that the "multi-level return" coderef represents a single-use/upward-only continuation.


The following functions are available (and can be imported on demand).

with_return BLOCK

Executes BLOCK, passing it a code reference (called $return in this description) as a single argument. Returns whatever BLOCK returns.

If $return is called, it causes an immediate return from with_return. Any arguments passed to $return become with_return's return value (if with_return is in scalar context, it will return the last argument passed to $return).

It is an error to invoke $return after its surrounding BLOCK has finished executing. In particular, it is an error to call $return twice.


This module uses unwind from Scope::Upper to do its work. If Scope::Upper is not available, it substitutes its own pure Perl implementation. You can force the pure Perl version to be used regardless by setting the environment variable RETURN_MULTILEVEL_PP to 1.

If you get the error message Attempt to re-enter dead call frame, that means something has called a $return from outside of its with_return { ... } block. You can get a stack trace of where that with_return was by setting the environment variable RETURN_MULTILEVEL_DEBUG to 1.


You can't use this module to return across implicit function calls, such as signal handlers (like $SIG{ALRM}) or destructors (sub DESTROY { ... }). These are invoked automatically by perl and not part of the normal call chain.


  • Lukas Mai

  • Graham Ollis <>


This software is copyright (c) 2013,2014,2021 by Lukas Mai.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.