Make the new method in CMOP::Method::Generated throw an error. This is an abstract...
[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.78';
10 $VERSION = eval $VERSION;
11 our $AUTHORITY = 'cpan:STEVAN';
12
13 use base 'Class::MOP::Method';
14
15 ## accessors
16
17 sub new {
18     confess __PACKAGE__ . " is an abstract base class, you must provide a constructor.";
19 }
20
21 sub is_inline { $_[0]{is_inline} }
22
23 sub definition_context { $_[0]{definition_context} }
24
25 sub initialize_body {
26     confess "No body to initialize, " . __PACKAGE__ . " is an abstract base class";
27 }
28
29 sub _eval_closure {
30     # my ($self, $captures, $sub_body) = @_;
31     my $__captures = $_[1];
32     eval join(
33         "\n",
34         (
35             map {
36                 /^([\@\%\$])/
37                     or die "capture key should start with \@, \% or \$: $_";
38                 q[my ]
39                 . $_ . q[ = ]
40                 . $1
41                 . q[{$__captures->{']
42                 . $_
43                 . q['}};];
44             } keys %$__captures
45         ),
46         $_[2]
47     );
48 }
49
50 sub _add_line_directive {
51     my ( $self, %args ) = @_;
52
53     my ( $line, $file );
54
55     if ( my $ctx = ( $args{context} || $self->definition_context ) ) {
56         $line = $ctx->{line};
57         if ( my $desc = $ctx->{description} ) {
58             $file = "$desc defined at $ctx->{file}";
59         } else {
60             $file = $ctx->{file};
61         }
62     } else {
63         ( $line, $file ) = ( 0, "generated method (unknown origin)" );
64     }
65
66     my $code = $args{code};
67
68     # if it's an array of lines, join it up
69     # don't use newlines so that the definition context is more meaningful
70     $code = join(@$code, ' ') if ref $code;
71
72     return qq{#line $line "$file"\n} . $code;
73 }
74
75 sub _compile_code {
76     my ( $self, %args ) = @_;
77
78     my $code = $self->_add_line_directive(%args);
79
80     $self->_eval_closure($args{environment}, $code);
81 }
82
83 1;
84
85 __END__
86
87 =pod
88
89 =head1 NAME 
90
91 Class::MOP::Method::Generated - Abstract base class for generated methods
92
93 =head1 DESCRIPTION
94
95 This is a C<Class::MOP::Method> subclass which is used interally 
96 by C<Class::MOP::Method::Accessor> and C<Class::MOP::Method::Constructor>.
97
98 =head1 METHODS
99
100 =over 4
101
102 =item B<new (%options)>
103
104 This creates the method based on the criteria in C<%options>, 
105 these options are:
106
107 =over 4
108
109 =item I<is_inline>
110
111 This is a boolean to indicate if the method should be generated
112 as a closure, or as a more optimized inline version.
113
114 =back
115
116 =item B<is_inline>
117
118 This returns the boolean which was passed into C<new>.
119
120 =item B<initialize_body>
121
122 This is an abstract method and will throw an exception if called.
123
124 =back
125
126 =head1 AUTHORS
127
128 Stevan Little E<lt>stevan@iinteractive.comE<gt>
129
130 =head1 COPYRIGHT AND LICENSE
131
132 Copyright 2006-2009 by Infinity Interactive, Inc.
133
134 L<http://www.iinteractive.com>
135
136 This library is free software; you can redistribute it and/or modify
137 it under the same terms as Perl itself. 
138
139 =cut
140