The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

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. Note that for performance reasons all quoted subs declared so far will be globally unquoted/parsed in a single eval. This means that if you have a syntax error in one of your quoted subs you may find out when some other sub is unquoted.

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 {
   '$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 {
   '$x' => 1,
   '$y' => 2,
 };

Generates a snippet of code which is suitable to be used as a prelude for "inlinify". The keys are the names of the variables and the values are (duh) the values. Note that references work as values.