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