Sub-Block
view release on metacpan or search on metacpan
lib/Sub/Block.pm view on Meta::CPAN
use 5.008;
use strict;
use warnings;
package Sub::Block;
our $AUTHORITY = 'cpan:TOBYINK';
our $VERSION = '0.002';
use Moo;
use Carp qw(carp croak);
use Exporter::Tiny qw();
use Scalar::Util qw(blessed refaddr);
use Sub::Quote qw();
use namespace::clean;
{
our @ISA = 'Exporter::Tiny';
our @EXPORT = 'block';
sub _generate_block {
my $class = shift;
sub (&) { $class->new(@_) };
}
}
use overload (
q[&{}] => sub { $_[0]{sub} },
q[>>] => sub { __PACKAGE__->sequence($_[2] ? @_[1,0] : @_[0,1]) },
);
has sub => (is => 'ro', required => 1);
has [qw/ map grep /] => (is => 'lazy');
my $deparse;
sub BUILDARGS
{
my $class = shift;
if (@_ == 1 and ref($_[0]) eq q(HASH))
{
return $_[0];
}
elsif (@_ == 1 and ref($_[0]) eq q(CODE))
{
require B::Deparse;
require PadWalker;
$deparse ||= 'B::Deparse'->new;
my $coderef = shift;
$class->_check_coderef($coderef);
my $closures = PadWalker::closed_over($coderef);
my $perlcode = $deparse->coderef2text($coderef);
$perlcode =~ s/(?:\A\{)|(?:\}\z)//g;
return +{ sub => Sub::Quote::quote_sub($perlcode, $closures) }
}
else
{
return +{ sub => scalar Sub::Quote::quote_sub(@_) };
}
}
sub _check_coderef
{
require B;
my $class = shift;
my ($coderef) = @_;
local *B::OP::__Sub_Block_callback = sub
{
my $name = $_[0]->name;
return if $name ne 'return' && $name ne 'wantarray';
local $Carp::CarpLevel = $Carp::CarpLevel + 2;
carp("Coderef $coderef appears to contain an explicit `$name` statement; not suitable for inlining");
};
B::svref_2object($coderef)->ROOT->B::walkoptree('__Sub_Block_callback');
}
sub execute
{
my $self = shift;
my $sub = $self->{sub};
goto $sub;
}
sub code
{
Sub::Quote::quoted_from_sub( $_[0]->{sub} )->[1];
}
sub closures
{
Sub::Quote::quoted_from_sub( $_[0]->{sub} )->[2];
}
sub inlinify
{
my $self = shift;
Sub::Quote::inlinify($self->code, join(q[,], @_), '', 1);
}
sub sequence
{
my $class = __PACKAGE__;
$class = shift if !ref $_[0];
my @subs = map { blessed($_) ? $_ : $class->new($_) } @_;
my $code = '';
my $vars = {};
( run in 0.778 second using v1.01-cache-2.11-cpan-39bf76dae61 )