X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FClass%2FMOP%2FMethod%2FGenerated.pm;h=cb4b1b0385f0d14fd5b2297d7ee32c8b8489aa82;hb=53362bcb1b32d87630190fbf50679dc37bb51adf;hp=cc5a4270925bbb877233b0c52db932ac7ce873b1;hpb=cacb672eae8fe9b02d53dc4e82c39091d401b4f8;p=gitmo%2FClass-MOP.git diff --git a/lib/Class/MOP/Method/Generated.pm b/lib/Class/MOP/Method/Generated.pm index cc5a427..cb4b1b0 100644 --- a/lib/Class/MOP/Method/Generated.pm +++ b/lib/Class/MOP/Method/Generated.pm @@ -6,45 +6,114 @@ use warnings; use Carp 'confess'; -our $VERSION = '0.72'; +our $VERSION = '1.11'; $VERSION = eval $VERSION; our $AUTHORITY = 'cpan:STEVAN'; use base 'Class::MOP::Method'; +## accessors + sub new { - my $class = shift; - my %options = @_; - - ($options{package_name} && $options{name}) - || confess "You must supply the package_name and name parameters $Class::MOP::Method::UPGRADE_ERROR_TEXT"; - - my $self = $class->_new(\%options); - - $self->initialize_body; - - return $self; + confess __PACKAGE__ . " is an abstract base class, you must provide a constructor."; } -sub _new { - my $class = shift; - my $options = @_ == 1 ? $_[0] : {@_}; +sub _initialize_body { + confess "No body to initialize, " . __PACKAGE__ . " is an abstract base class"; +} - $options->{is_inline} ||= 0; - $options->{body} ||= undef; +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 ); +} - bless $options, $class; +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; + } + + print STDERR "\n", $self->name, ":\n", $output, "\n"; } -## accessors +sub _add_line_directive { + my ( $self, %args ) = @_; -sub is_inline { (shift)->{'is_inline'} } + my ( $line, $file ); -sub initialize_body { - confess "No body to initialize, " . __PACKAGE__ . " is an abstract base class"; + 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); + return $self->_eval_closure($args{environment}, $code); +} 1; @@ -58,36 +127,11 @@ Class::MOP::Method::Generated - Abstract base class for generated methods =head1 DESCRIPTION -This is a C subclass which is used interally -by C and C. - -=head1 METHODS - -=over 4 - -=item B - -This creates the method based on the criteria in C<%options>, -these options are: - -=over 4 - -=item I - -This is a boolean to indicate if the method should be generated -as a closure, or as a more optimized inline version. - -=back - -=item B - -This returns the boolean which was passed into C. - -=item B - -This is an abstract method and will throw an exception if called. +This is a C subclass which is subclassed by +C and +C. -=back +It is not intended to be used directly. =head1 AUTHORS @@ -95,7 +139,7 @@ Stevan Little Estevan@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2006-2008 by Infinity Interactive, Inc. +Copyright 2006-2010 by Infinity Interactive, Inc. L