requires 'Carp';
requires 'Data::OptList';
requires 'Devel::GlobalDestruction';
+requires 'Eval::Closure';
requires 'List::MoreUtils' => '0.12';
requires 'MRO::Compat' => '0.05';
requires 'Package::DeprecationManager' => '0.10';
use Carp 'confess';
use Scalar::Util 'blessed', 'weaken';
+use Try::Tiny;
our $VERSION = '1.11';
$VERSION = eval $VERSION;
my $self = shift;
my $attr = $self->associated_attribute;
- my ( $code, $e ) = $self->_eval_closure(
- {},
- 'sub {'
- . $attr->inline_set( '$_[0]', '$_[1]' )
- . ' if scalar(@_) == 2; '
- . $attr->inline_get('$_[0]') . '}'
- );
- confess "Could not generate inline accessor because : $e" if $e;
+ my $code = try {
+ $self->_compile_code(
+ source => [
+ 'sub {',
+ $attr->inline_set( '$_[0]', '$_[1]' )
+ . ' if scalar(@_) == 2;',
+ $attr->inline_get('$_[0]') . ';',
+ '}',
+ ]
+ );
+ }
+ catch {
+ confess "Could not generate inline accessor because : $_";
+ };
return $code;
}
my $self = shift;
my $attr = $self->associated_attribute;
- my ( $code, $e ) = $self->_eval_closure(
- {},
- 'sub {'
- . 'confess "Cannot assign a value to a read-only accessor" if @_ > 1;'
- . $attr->inline_get('$_[0]') . '}'
- );
- confess "Could not generate inline reader because : $e" if $e;
+ my $code = try {
+ $self->_compile_code(
+ source => [
+ 'sub {',
+ 'confess "Cannot assign a value to a read-only accessor" '
+ . 'if @_ > 1;',
+ $attr->inline_get('$_[0]') . ';',
+ '}',
+ ],
+ );
+ }
+ catch {
+ confess "Could not generate inline reader because : $_";
+ };
return $code;
}
my $self = shift;
my $attr = $self->associated_attribute;
- my ( $code, $e ) = $self->_eval_closure(
- {},
- 'sub {' . $attr->inline_set( '$_[0]', '$_[1]' ) . '}'
- );
- confess "Could not generate inline writer because : $e" if $e;
+ my $code = try {
+ $self->_compile_code(
+ source => [
+ 'sub {',
+ $attr->inline_set( '$_[0]', '$_[1]' ) . ';',
+ '}',
+ ],
+ );
+ }
+ catch {
+ confess "Could not generate inline writer because : $_";
+ };
return $code;
}
my $self = shift;
my $attr = $self->associated_attribute;
- my ( $code, $e ) = $self->_eval_closure(
- {},
- 'sub {' . $attr->inline_has('$_[0]') . '}'
- );
- confess "Could not generate inline predicate because : $e" if $e;
+ my $code = try {
+ $self->_compile_code(
+ source => [
+ 'sub {',
+ $attr->inline_has('$_[0]') . ';',
+ '}',
+ ],
+ );
+ }
+ catch {
+ confess "Could not generate inline predicate because : $_";
+ };
return $code;
}
my $self = shift;
my $attr = $self->associated_attribute;
- my ( $code, $e ) = $self->_eval_closure(
- {},
- 'sub {' . $attr->inline_clear('$_[0]') . '}'
- );
- confess "Could not generate inline clearer because : $e" if $e;
+ my $code = try {
+ $self->_compile_code(
+ source => [
+ 'sub {',
+ $attr->inline_clear('$_[0]') . ';',
+ '}',
+ ],
+ );
+ }
+ catch {
+ confess "Could not generate inline clearer because : $_";
+ };
return $code;
}
use Carp 'confess';
use Scalar::Util 'blessed', 'weaken';
+use Try::Tiny;
our $VERSION = '1.11';
$VERSION = eval $VERSION;
$source .= ";\n" . '}';
warn $source if $self->options->{debug};
- my ( $code, $e ) = $self->_eval_closure(
- $close_over,
- $source
- );
- confess "Could not eval the constructor :\n\n$source\n\nbecause :\n\n$e" if $e;
+ my $code = try {
+ $self->_compile_code(
+ source => $source,
+ environment => $close_over,
+ );
+ }
+ catch {
+ confess "Could not eval the constructor :\n\n$source\n\nbecause :\n\n$_";
+ };
return $code;
}
use warnings;
use Carp 'confess';
+use Eval::Closure;
our $VERSION = '1.11';
$VERSION = eval $VERSION;
confess "No body to initialize, " . __PACKAGE__ . " is an abstract base class";
}
-sub _eval_closure {
- my ($self, $__captures, $sub_body) = @_;
-
- my $code;
-
- my $e = do {
- local $@;
- local $SIG{__DIE__};
- my $source = join
- "\n", (
- map {
- /^([\@\%\$])/
- or die "capture key should start with \@, \% or \$: $_";
- q[my ]
- . $_ . q[ = ]
- . $1
- . q[{$__captures->{']
- . $_ . q['}};];
- } keys %$__captures
- ),
- $sub_body;
-
- $self->_dump_source($source) if $ENV{MOP_PRINT_SOURCE};
-
- $code = eval $source;
- $@;
- };
-
- return ( $code, $e );
-}
-
-sub _dump_source {
- my ( $self, $source ) = @_;
-
- my $output;
- if ( eval { require Perl::Tidy } ) {
- require File::Spec;
-
- my $rc_file = File::Spec->catfile(
- $INC{'Class/MOP/Method/Generated.pm'},
- ('..') x 5,
- 'perltidyrc'
- );
-
- my %p = (
- source => \$source,
- destination => \$output,
- );
- $p{perltidyrc} = $rc_file
- if -f $rc_file;
-
- Perl::Tidy::perltidy(%p);
- }
- else {
- $output = $source;
- }
+sub _generate_description {
+ my ( $self, $context ) = @_;
+ $context ||= $self->definition_context;
- print STDERR "\n", $self->name, ":\n", $output, "\n";
-}
-
-sub _add_line_directive {
- my ( $self, %args ) = @_;
+ return "generated method (unknown origin)"
+ unless defined $context;
- my ( $line, $file );
-
- if ( my $ctx = ( $args{context} || $self->definition_context ) ) {
- $line = $ctx->{line};
- if ( my $desc = $ctx->{description} ) {
- $file = "$desc defined at $ctx->{file}";
- } else {
- $file = $ctx->{file};
- }
+ if (defined $context->{description}) {
+ return "$context->{description} "
+ . "(defined at $context->{file} line $context->{line})";
} else {
- ( $line, $file ) = ( 0, "generated method (unknown origin)" );
+ return "$context->{file} (line $context->{line})";
}
-
- my $code = $args{code};
-
- # if it's an array of lines, join it up
- # don't use newlines so that the definition context is more meaningful
- $code = join(@$code, ' ') if ref $code;
-
- return qq{#line $line "$file"\n} . $code;
}
sub _compile_code {
- my ( $self, %args ) = @_;
-
- my $code = $self->_add_line_directive(%args);
-
- return $self->_eval_closure($args{environment}, $code);
+ my ( $self, @args ) = @_;
+ unshift @args, 'source' if @args % 2;
+ my %args = @args;
+
+ my $context = delete $args{context};
+ my $environment = $self->can('_eval_environment')
+ ? $self->_eval_environment
+ : {};
+
+ return eval_closure(
+ environment => $environment,
+ description => $self->_generate_description($context),
+ %args,
+ );
}
1;
sub _inline_destructor {
my $self = shift;
- my ( $code, $e ) = $self->_eval_closure( {}, 'sub { }' );
- die $e if $e;
+ my $code = $self->_compile_code(source => 'sub { }');
$self->{body} = $code;
}