2 package Class::MOP::Method;
8 use Scalar::Util 'reftype', 'blessed';
11 our $VERSION = '0.03';
12 our $AUTHORITY = 'cpan:STEVAN';
14 use overload '&{}' => sub { $_[0]->{body} },
20 require Class::MOP::Class;
21 Class::MOP::Class->initialize(blessed($_[0]) || $_[0]);
29 ('CODE' eq (reftype($code) || ''))
30 || confess "You must supply a CODE reference to bless, not (" . ($code || 'undef') . ")";
33 } => blessed($class) || $class;
36 sub body { (shift)->{body} }
41 my $code = (shift)->{body};
42 svref_2object($code)->GV->STASH->NAME;
46 my $code = (shift)->{body};
47 svref_2object($code)->GV->NAME;
50 sub fully_qualified_name {
52 $code->package_name . '::' . $code->name;
55 package Class::MOP::Method::Wrapped;
61 use Scalar::Util 'reftype', 'blessed';
62 use Sub::Name 'subname';
64 our $VERSION = '0.01';
66 use base 'Class::MOP::Method';
69 # this ugly beast is the result of trying
70 # to micro optimize this as much as possible
71 # while not completely loosing maintainability.
72 # At this point it's "fast enough", after all
73 # you can't get something for nothing :)
74 my $_build_wrapped_method = sub {
75 my $modifier_table = shift;
76 my ($before, $after, $around) = (
77 $modifier_table->{before},
78 $modifier_table->{after},
79 $modifier_table->{around},
81 if (@$before && @$after) {
82 $modifier_table->{cache} = sub {
83 $_->(@_) for @{$before};
85 ((defined wantarray) ?
87 (@rval = $around->{cache}->(@_))
89 ($rval[0] = $around->{cache}->(@_)))
91 $around->{cache}->(@_));
92 $_->(@_) for @{$after};
93 return unless defined wantarray;
94 return wantarray ? @rval : $rval[0];
97 elsif (@$before && !@$after) {
98 $modifier_table->{cache} = sub {
99 $_->(@_) for @{$before};
100 return $around->{cache}->(@_);
103 elsif (@$after && !@$before) {
104 $modifier_table->{cache} = sub {
106 ((defined wantarray) ?
108 (@rval = $around->{cache}->(@_))
110 ($rval[0] = $around->{cache}->(@_)))
112 $around->{cache}->(@_));
113 $_->(@_) for @{$after};
114 return unless defined wantarray;
115 return wantarray ? @rval : $rval[0];
119 $modifier_table->{cache} = $around->{cache};
126 (blessed($code) && $code->isa('Class::MOP::Method'))
127 || confess "Can only wrap blessed CODE";
128 my $modifier_table = {
134 cache => $code->body,
138 $_build_wrapped_method->($modifier_table);
139 my $method = $class->SUPER::wrap(sub { $modifier_table->{cache}->(@_) });
140 $method->{modifier_table} = $modifier_table;
144 sub get_original_method {
146 $code->{modifier_table}->{orig};
149 sub add_before_modifier {
151 my $modifier = shift;
152 unshift @{$code->{modifier_table}->{before}} => $modifier;
153 $_build_wrapped_method->($code->{modifier_table});
156 sub add_after_modifier {
158 my $modifier = shift;
159 push @{$code->{modifier_table}->{after}} => $modifier;
160 $_build_wrapped_method->($code->{modifier_table});
165 # this is another possible canidate for
166 # optimization as well. There is an overhead
167 # associated with the currying that, if
168 # eliminated might make around modifiers
170 my $compile_around_method = sub {{
172 return $f1 unless @_;
174 push @_, sub { $f2->( $f1, @_ ) };
178 sub add_around_modifier {
180 my $modifier = shift;
181 unshift @{$code->{modifier_table}->{around}->{methods}} => $modifier;
182 $code->{modifier_table}->{around}->{cache} = $compile_around_method->(
183 @{$code->{modifier_table}->{around}->{methods}},
184 $code->{modifier_table}->{orig}->body
186 $_build_wrapped_method->($code->{modifier_table});
198 Class::MOP::Method - Method Meta Object
202 # ... more to come later maybe
206 The Method Protocol is very small, since methods in Perl 5 are just
207 subroutines within the particular package. Basically all we do is to
208 bless the subroutine.
210 Currently this package is largely unused. Future plans are to provide
211 some very simple introspection methods for the methods themselves.
212 Suggestions for this are welcome.
222 This will return a B<Class::MOP::Class> instance which is related
231 =item B<wrap (&code)>
233 This simply blesses the C<&code> reference passed to it.
245 =item B<package_name>
247 =item B<fully_qualified_name>
251 =head1 Class::MOP::Method::Wrapped METHODS
257 =item B<wrap (&code)>
259 This simply blesses the C<&code> reference passed to it.
261 =item B<get_original_method>
269 =item B<add_before_modifier ($code)>
271 =item B<add_after_modifier ($code)>
273 =item B<add_around_modifier ($code)>
279 Stevan Little E<lt>stevan@iinteractive.comE<gt>
281 Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
283 =head1 COPYRIGHT AND LICENSE
285 Copyright 2006 by Infinity Interactive, Inc.
287 L<http://www.iinteractive.com>
289 This library is free software; you can redistribute it and/or modify
290 it under the same terms as Perl itself.