NAME
Sub::Quote - efficient generation of subroutines via string eval
SYNOPSIS
package Silly;
use Sub::Quote qw(quote_sub unquote_sub quoted_from_sub);
quote_sub 'Silly::kitty', q{ print "meow" };
quote_sub 'Silly::doggy', q{ print "woof" };
my $sound = 0;
quote_sub 'Silly::dagron',
q{ print ++$sound % 2 ? 'burninate' : 'roar' },
{ '$sound' => \$sound };
And elsewhere:
Silly->kitty; # meow
Silly->doggy; # woof
Silly->dagron; # burninate
Silly->dagron; # roar
Silly->dagron; # burninate
DESCRIPTION
This package provides performant ways to generate subroutines from strings.
SUBROUTINES
quote_sub
my $coderef = quote_sub 'Foo::bar', q{ print $x++ . "\n" }, { '$x' => \0 };
Arguments: ?$name, $code, ?\%captures, ?\%options
$name
is the subroutine where the coderef will be installed.
$code
is a string that will be turned into code.
\%captures
is a hashref of variables that will be made available to the code. See the "SYNOPSIS"'s Silly::dagron
for an example using captures.
options
no_install
Boolean. Set this option to not install the generated coderef into the passed subroutine name on undefer.
unquote_sub
my $coderef = unquote_sub $sub;
Forcibly replace subroutine with actual code.
If $sub is not a quoted sub, this is a no-op.
quoted_from_sub
my $data = quoted_from_sub $sub;
my ($name, $code, $captures, $compiled_sub) = @$data;
Returns original arguments to quote_sub, plus the compiled version if this sub has already been unquoted.
Note that $sub can be either the original quoted version or the compiled version for convenience.
inlinify
my $prelude = capture_unroll '$captures', {
'$x' => 1,
'$y' => 2,
};
my $inlined_code = inlinify q{
my ($x, $y) = @_;
print $x + $y . "\n";
}, '$x, $y', $prelude;
Takes a string of code, a string of arguments, a string of code which acts as a "prelude", and a Boolean representing whether or not to localize the arguments.
capture_unroll
my $prelude = capture_unroll '$captures', {
'$x' => 1,
'$y' => 2,
}, 4;
Arguments: $from, \%captures, $indent
Generates a snippet of code which is suitable to be used as a prelude for "inlinify". $from
is a string will be used as a hashref in the resulting code. The keys of %captures
are the names of the variables and the values are ignored. $indent
is the number of spaces to indent the result by.
CAVEATS
Much of this is just string-based code-generation, and as a result, a few caveats apply.
return
Calling return
from a quote_sub'ed sub will not likely do what you intend. Instead of returning from the code you defined in quote_sub
, it will return from the overall function it is composited into.
So when you pass in:
quote_sub q{ return 1 if $condition; $morecode }
It might turn up in the intended context as follows:
sub foo {
<important code a>
do {
return 1 if $condition;
$morecode
};
<important code b>
}
Which will obviously return from foo, when all you meant to do was return from the code context in quote_sub and proceed with running important code b.
strictures
Sub::Quote compiles quoted subs in an environment where use strictures
is in effect. strictures enables strict and FATAL warnings.
The following dies Use of uninitialized value in print...
no warnings;
quote_sub 'Silly::kitty', q{ print undef };
If you need to disable parts of strictures, do it within the quoted sub:
quote_sub 'Silly::kitty', q{ no warnings; print undef };
SUPPORT
See Moo for support and contact information.
AUTHORS
See Moo for authors.
COPYRIGHT AND LICENSE
See Moo for the copyright and license.