diff --git a/Changes b/Changes index ae8b239..7dedd1a 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,8 @@ Revision history for {{$dist->name}} {{$NEXT}} + - Remove the most uses of stringy eval (gh#6) One still remains + - Remove dependency on Data::Munge (gh#6) 0.06 2021-10-11 16:57:42 -0600 - Fixed test bug (rt#133221) diff --git a/lib/Return/MultiLevel.pm b/lib/Return/MultiLevel.pm index af17dcc..4dfe6be 100644 --- a/lib/Return/MultiLevel.pm +++ b/lib/Return/MultiLevel.pm @@ -4,7 +4,6 @@ use strict; use warnings; use 5.008001; use Carp qw(confess); -use Data::Munge qw(eval_string); use parent 'Exporter'; # ABSTRACT: Return across multiple call levels @@ -14,90 +13,82 @@ our @EXPORT_OK = qw(with_return); our $_backend; +sub with_return (&); + if (!$ENV{RETURN_MULTILEVEL_PP} && eval { require Scope::Upper }) { - eval_string <<'EOT'; -sub with_return (&) { + + *with_return = sub (&) { my ($f) = @_; my $ctx = Scope::Upper::HERE(); - my @canary = - !$ENV{RETURN_MULTILEVEL_DEBUG} - ? '-' - : Carp::longmess "Original call to with_return" - ; + my @canary = !$ENV{RETURN_MULTILEVEL_DEBUG} + ? '-' + : Carp::longmess "Original call to with_return"; + local $canary[0]; $f->(sub { - $canary[0] - and confess - $canary[0] eq '-' - ? "" - : "Captured stack:\n$canary[0]\n", - "Attempt to re-enter dead call frame" - ; - Scope::Upper::unwind(@_, $ctx); + $canary[0] and confess $canary[0] eq '-' + ? "" + : "Captured stack:\n$canary[0]\n", + "Attempt to re-enter dead call frame"; + Scope::Upper::unwind(@_, $ctx); }) -} -EOT + }; - $_backend = 'XS'; + $_backend = 'XS'; } else { - eval_string <<'EOT'; -{ + *_label_at = do { my $_label_prefix = '_' . __PACKAGE__ . '_'; $_label_prefix =~ tr/A-Za-z0-9_/_/cs; - sub _label_at { $_label_prefix . $_[0] } -} + sub { $_label_prefix . $_[0] }; + }; -our @_trampoline_cache; + our @_trampoline_cache; -sub _get_trampoline { + *_get_trampoline = sub { my ($i) = @_; - my $label = _label_at $i; + my $label = _label_at($i); ( - $label, - $_trampoline_cache[$i] ||= eval_string qq{ - sub { - my \$rr = shift; - my \$fn = shift; - return &\$fn; - $label: splice \@\$rr - } - }, + $label, + $_trampoline_cache[$i] ||= eval ## no critic (BuiltinFunctions::ProhibitStringyEval) + qq{ + sub { + my \$rr = shift; + my \$fn = shift; + return &\$fn; + $label: splice \@\$rr + } + }, ) -} + }; -our $_depth = 0; + our $_depth = 0; -sub with_return (&) { + *with_return = sub (&) { my ($f) = @_; - my ($label, $trampoline) = _get_trampoline $_depth; + my ($label, $trampoline) = _get_trampoline($_depth); local $_depth = $_depth + 1; - my @canary = - !$ENV{RETURN_MULTILEVEL_DEBUG} - ? '-' - : Carp::longmess "Original call to with_return" - ; + my @canary = !$ENV{RETURN_MULTILEVEL_DEBUG} + ? '-' + : Carp::longmess "Original call to with_return"; + local $canary[0]; my @ret; $trampoline->( - \@ret, - $f, - sub { - $canary[0] - and confess - $canary[0] eq '-' - ? "" - : "Captured stack:\n$canary[0]\n", - "Attempt to re-enter dead call frame" - ; - @ret = @_; - goto $label; - }, + \@ret, + $f, + sub { + $canary[0] and confess $canary[0] eq '-' + ? "" + : "Captured stack:\n$canary[0]\n", + "Attempt to re-enter dead call frame"; + @ret = @_; + goto $label; + }, ) -} -EOT + }; $_backend = 'PP'; } diff --git a/t/00_diag.t b/t/00_diag.t index b9168e2..9e0370c 100644 --- a/t/00_diag.t +++ b/t/00_diag.t @@ -11,7 +11,6 @@ my $post_diag; $modules{$_} = $_ for qw( Carp - Data::Munge Exporter ExtUtils::MakeMaker Scope::Upper diff --git a/t/basic.t b/t/basic.t index bdf0112..a2cdd48 100644 --- a/t/basic.t +++ b/t/basic.t @@ -3,6 +3,15 @@ use warnings; use Test::More tests => 5; use Return::MultiLevel qw(with_return); +diag ''; +diag ''; +diag ''; + +diag "backend = @{[ $Return::MultiLevel::_backend ]}"; + +diag ''; +diag ''; + is with_return { my ($ret) = @_; 42