X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FClass%2FMOP%2FMethod%2FGenerated.pm;h=cbcc356201a02e68319e79bba52d1441dd34c469;hb=b4bd10ecd2eabe1a2c1bc3addad22b207f6592ee;hp=73141b3d73d74c6e759cd4c09bbb73f07eb0b718;hpb=7fe03d203ea938d46cfb8f546181ef271d5a81bd;p=gitmo%2FClass-MOP.git diff --git a/lib/Class/MOP/Method/Generated.pm b/lib/Class/MOP/Method/Generated.pm index 73141b3..cbcc356 100644 --- a/lib/Class/MOP/Method/Generated.pm +++ b/lib/Class/MOP/Method/Generated.pm @@ -6,7 +6,8 @@ use warnings; use Carp 'confess'; -our $VERSION = '0.64'; +our $VERSION = '0.77'; +$VERSION = eval $VERSION; our $AUTHORITY = 'cpan:STEVAN'; use base 'Class::MOP::Method'; @@ -18,29 +19,86 @@ sub new { ($options{package_name} && $options{name}) || confess "You must supply the package_name and name parameters $Class::MOP::Method::UPGRADE_ERROR_TEXT"; - my $self = bless { - # from our superclass - '&!body' => undef, - '$!package_name' => $options{package_name}, - '$!name' => $options{name}, - # specific to this subclass - '$!is_inline' => ($options{is_inline} || 0), - } => $class; + my $self = $class->_new(\%options); $self->initialize_body; return $self; } +sub _new { + my $class = shift; + my $options = @_ == 1 ? $_[0] : {@_}; + + $options->{is_inline} ||= 0; + $options->{body} ||= undef; + + bless $options, $class; +} + ## accessors -sub is_inline { (shift)->{'$!is_inline'} } +sub is_inline { $_[0]{is_inline} } + +sub definition_context { $_[0]{definition_context} } sub initialize_body { confess "No body to initialize, " . __PACKAGE__ . " is an abstract base class"; } +sub _eval_closure { + # my ($self, $captures, $sub_body) = @_; + my $__captures = $_[1]; + eval join( + "\n", + ( + map { + /^([\@\%\$])/ + or die "capture key should start with \@, \% or \$: $_"; + q[my ] + . $_ . q[ = ] + . $1 + . q[{$__captures->{'] + . $_ + . q['}};]; + } keys %$__captures + ), + $_[2] + ); +} + +sub _add_line_directive { + my ( $self, %args ) = @_; + + 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}; + } + } else { + ( $line, $file ) = ( 0, "generated method (unknown origin)" ); + } + + 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); + + $self->_eval_closure($args{environment}, $code); +} 1;