Update Changes, bump version to 0.97_01, make copyright 2006-2010
[gitmo/Class-MOP.git] / lib / Class / MOP / Method / Generated.pm
1
2 package Class::MOP::Method::Generated;
3
4 use strict;
5 use warnings;
6
7 use Carp 'confess';
8
9 our $VERSION   = '0.97_01';
10 $VERSION = eval $VERSION;
11 our $AUTHORITY = 'cpan:STEVAN';
12
13 use base 'Class::MOP::Method';
14
15 use constant _PRINT_SOURCE => $ENV{MOP_PRINT_SOURCE} ? 1 : 0;
16
17 ## accessors
18
19 sub new {
20     confess __PACKAGE__ . " is an abstract base class, you must provide a constructor.";
21 }
22
23 sub is_inline { $_[0]{is_inline} }
24
25 sub definition_context { $_[0]{definition_context} }
26
27 sub _initialize_body {
28     confess "No body to initialize, " . __PACKAGE__ . " is an abstract base class";
29 }
30
31 sub _eval_closure {
32     # my ($self, $captures, $sub_body) = @_;
33     my $__captures = $_[1];
34
35     my $code;
36
37     my $e = do {
38         local $@;
39         local $SIG{__DIE__};
40         my $source = join
41             "\n", (
42             map {
43                 /^([\@\%\$])/
44                     or die "capture key should start with \@, \% or \$: $_";
45                 q[my ] 
46                     . $_ . q[ = ] 
47                     . $1
48                     . q[{$__captures->{']
49                     . $_ . q['}};];
50                 } keys %$__captures
51             ),
52             $_[2];
53         print STDERR "\n", $_[0]->name, ":\n", $source, "\n" if _PRINT_SOURCE;
54         $code = eval $source;
55         $@;
56     };
57
58     return ( $code, $e );
59 }
60
61 sub _add_line_directive {
62     my ( $self, %args ) = @_;
63
64     my ( $line, $file );
65
66     if ( my $ctx = ( $args{context} || $self->definition_context ) ) {
67         $line = $ctx->{line};
68         if ( my $desc = $ctx->{description} ) {
69             $file = "$desc defined at $ctx->{file}";
70         } else {
71             $file = $ctx->{file};
72         }
73     } else {
74         ( $line, $file ) = ( 0, "generated method (unknown origin)" );
75     }
76
77     my $code = $args{code};
78
79     # if it's an array of lines, join it up
80     # don't use newlines so that the definition context is more meaningful
81     $code = join(@$code, ' ') if ref $code;
82
83     return qq{#line $line "$file"\n} . $code;
84 }
85
86 sub _compile_code {
87     my ( $self, %args ) = @_;
88
89     my $code = $self->_add_line_directive(%args);
90
91     return $self->_eval_closure($args{environment}, $code);
92 }
93
94 1;
95
96 __END__
97
98 =pod
99
100 =head1 NAME 
101
102 Class::MOP::Method::Generated - Abstract base class for generated methods
103
104 =head1 DESCRIPTION
105
106 This is a C<Class::MOP::Method> subclass which is subclassed by
107 C<Class::MOP::Method::Accessor> and
108 C<Class::MOP::Method::Constructor>.
109
110 It is not intended to be used directly.
111
112 =head1 AUTHORS
113
114 Stevan Little E<lt>stevan@iinteractive.comE<gt>
115
116 =head1 COPYRIGHT AND LICENSE
117
118 Copyright 2006-2010 by Infinity Interactive, Inc.
119
120 L<http://www.iinteractive.com>
121
122 This library is free software; you can redistribute it and/or modify
123 it under the same terms as Perl itself. 
124
125 =cut
126