X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FClass%2FMOP%2FMethod%2FGenerated.pm;h=92751730c6bcc04595048aa94102323dc739e76a;hb=ea23e618007d485838d922d35c709936e09e9a35;hp=0b3456a7c384ac0d1d7440800c58428f2c5b2157;hpb=69e3ab0a5a391925610bbb917d81da8d53fd1b91;p=gitmo%2FClass-MOP.git diff --git a/lib/Class/MOP/Method/Generated.pm b/lib/Class/MOP/Method/Generated.pm index 0b3456a..9275173 100644 --- a/lib/Class/MOP/Method/Generated.pm +++ b/lib/Class/MOP/Method/Generated.pm @@ -6,79 +6,104 @@ use warnings; use Carp 'confess'; -our $VERSION = '0.01'; +our $VERSION = '0.87'; +$VERSION = eval $VERSION; our $AUTHORITY = 'cpan:STEVAN'; use base 'Class::MOP::Method'; +## accessors + sub new { - my $class = shift; - my %options = @_; - - my $self = bless { - # from our superclass - '&!body' => undef, - # specific to this subclass - '$!is_inline' => ($options{is_inline} || 0), - } => $class; - - $self->initialize_body; - - return $self; + confess __PACKAGE__ . " is an abstract base class, you must provide a constructor."; } -## accessors +sub is_inline { $_[0]{is_inline} } -sub is_inline { (shift)->{'$!is_inline'} } +sub definition_context { $_[0]{definition_context} } -sub initialize_body { +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]; + + my $code; + + my $e = do { + local $@; + local $SIG{__DIE__}; + $code = eval join + "\n", ( + map { + /^([\@\%\$])/ + or die "capture key should start with \@, \% or \$: $_"; + q[my ] + . $_ . q[ = ] + . $1 + . q[{$__captures->{'] + . $_ . q['}};]; + } keys %$__captures + ), + $_[2]; + $@; + }; + + return ( $code, $e ); +} +sub _add_line_directive { + my ( $self, %args ) = @_; -1; - -__END__ - -=pod - -=head1 NAME - -Class::MOP::Method::Generated - Abstract base class for generated methods + my ( $line, $file ); -=head1 DESCRIPTION + 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)" ); + } -This is a C subclass which is used interally -by C and C. + my $code = $args{code}; -=head1 METHODS + # 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; -=over 4 + return qq{#line $line "$file"\n} . $code; +} -=item B +sub _compile_code { + my ( $self, %args ) = @_; -This creates the method based on the criteria in C<%options>, -these options are: + my $code = $self->_add_line_directive(%args); -=over 4 + $self->_eval_closure($args{environment}, $code); +} -=item I +1; -This is a boolean to indicate if the method should be generated -as a closure, or as a more optimized inline version. +__END__ -=back +=pod -=item B +=head1 NAME -This returns the boolean which was passed into C. +Class::MOP::Method::Generated - Abstract base class for generated methods -=item B +=head1 DESCRIPTION -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 @@ -86,7 +111,7 @@ Stevan Little Estevan@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2006-2008 by Infinity Interactive, Inc. +Copyright 2006-2009 by Infinity Interactive, Inc. L