line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Class::MOP::Mixin::HasMethods; |
2
|
|
|
|
|
|
|
our $VERSION = '2.2206'; |
3
|
|
|
|
|
|
|
|
4
|
450
|
|
|
450
|
|
79670
|
use strict; |
|
450
|
|
|
|
|
971
|
|
|
450
|
|
|
|
|
13540
|
|
5
|
450
|
|
|
450
|
|
2377
|
use warnings; |
|
450
|
|
|
|
|
1010
|
|
|
450
|
|
|
|
|
13136
|
|
6
|
|
|
|
|
|
|
|
7
|
450
|
|
|
450
|
|
207627
|
use Class::MOP::Method::Meta; |
|
450
|
|
|
|
|
1290
|
|
|
450
|
|
|
|
|
15504
|
|
8
|
|
|
|
|
|
|
|
9
|
450
|
|
|
450
|
|
3129
|
use Scalar::Util 'blessed', 'reftype'; |
|
450
|
|
|
|
|
1041
|
|
|
450
|
|
|
|
|
24321
|
|
10
|
450
|
|
|
450
|
|
2819
|
use Sub::Util 1.40 'set_subname'; |
|
450
|
|
|
|
|
9839
|
|
|
450
|
|
|
|
|
21069
|
|
11
|
|
|
|
|
|
|
|
12
|
450
|
|
|
450
|
|
2854
|
use parent 'Class::MOP::Mixin'; |
|
450
|
|
|
|
|
1018
|
|
|
450
|
|
|
|
|
2257
|
|
13
|
|
|
|
|
|
|
|
14
|
10021
|
|
|
10021
|
|
67264
|
sub _meta_method_class { 'Class::MOP::Method::Meta' } |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
sub _add_meta_method { |
17
|
13044
|
|
|
13044
|
|
26540
|
my $self = shift; |
18
|
13044
|
|
|
|
|
28436
|
my ($name) = @_; |
19
|
13044
|
50
|
|
|
|
75443
|
my $existing_method = $self->can('find_method_by_name') |
20
|
|
|
|
|
|
|
? $self->find_method_by_name($name) |
21
|
|
|
|
|
|
|
: $self->get_method($name); |
22
|
13044
|
100
|
100
|
|
|
42802
|
return if $existing_method |
23
|
|
|
|
|
|
|
&& $existing_method->isa($self->_meta_method_class); |
24
|
12939
|
|
|
|
|
44008
|
$self->add_method( |
25
|
|
|
|
|
|
|
$name => $self->_meta_method_class->wrap( |
26
|
|
|
|
|
|
|
name => $name, |
27
|
|
|
|
|
|
|
package_name => $self->name, |
28
|
|
|
|
|
|
|
associated_metaclass => $self, |
29
|
|
|
|
|
|
|
) |
30
|
|
|
|
|
|
|
); |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
sub wrap_method_body { |
34
|
29251
|
|
|
29251
|
0
|
90623
|
my ( $self, %args ) = @_; |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
( $args{body} && 'CODE' eq reftype $args{body} ) |
37
|
29251
|
100
|
66
|
|
|
131844
|
|| $self->_throw_exception( CodeBlockMustBeACodeRef => instance => $self, |
38
|
|
|
|
|
|
|
params => \%args |
39
|
|
|
|
|
|
|
); |
40
|
29250
|
|
|
|
|
230765
|
$self->method_metaclass->wrap( |
41
|
|
|
|
|
|
|
package_name => $self->name, |
42
|
|
|
|
|
|
|
%args, |
43
|
|
|
|
|
|
|
); |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub add_method { |
47
|
179169
|
|
|
179169
|
0
|
374191
|
my ( $self, $method_name, $method ) = @_; |
48
|
179169
|
100
|
100
|
|
|
685322
|
( defined $method_name && length $method_name ) |
49
|
|
|
|
|
|
|
|| $self->_throw_exception( MustDefineAMethodName => instance => $self ); |
50
|
|
|
|
|
|
|
|
51
|
179166
|
|
|
|
|
475158
|
my $package_name = $self->name; |
52
|
|
|
|
|
|
|
|
53
|
179164
|
|
|
|
|
256822
|
my $body; |
54
|
179164
|
100
|
100
|
|
|
974389
|
if ( blessed($method) && $method->isa('Class::MOP::Method') ) { |
55
|
170324
|
|
|
|
|
412115
|
$body = $method->body; |
56
|
170324
|
100
|
|
|
|
461358
|
if ( $method->package_name ne $package_name ) { |
57
|
18407
|
|
|
|
|
50015
|
$method = $method->clone( |
58
|
|
|
|
|
|
|
package_name => $package_name, |
59
|
|
|
|
|
|
|
name => $method_name, |
60
|
|
|
|
|
|
|
); |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
170324
|
|
|
|
|
433528
|
$method->attach_to_class($self); |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
else { |
66
|
|
|
|
|
|
|
# If a raw code reference is supplied, its method object is not created. |
67
|
|
|
|
|
|
|
# The method object won't be created until required. |
68
|
8840
|
|
|
|
|
15173
|
$body = $method; |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
179164
|
|
|
|
|
1064447
|
$self->_method_map->{$method_name} = $method; |
72
|
|
|
|
|
|
|
|
73
|
179164
|
|
|
|
|
738414
|
my ($current_package, $current_name) = Class::MOP::get_code_info($body); |
74
|
|
|
|
|
|
|
|
75
|
179164
|
100
|
66
|
|
|
1719763
|
set_subname($package_name . '::' . $method_name, $body) |
76
|
|
|
|
|
|
|
unless defined $current_name && $current_name !~ /^__ANON__/; |
77
|
|
|
|
|
|
|
|
78
|
179164
|
|
|
|
|
786098
|
$self->add_package_symbol("&$method_name", $body); |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
# we added the method to the method map too, so it's still valid |
81
|
179164
|
|
|
|
|
538284
|
$self->update_package_cache_flag; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub _code_is_mine { |
85
|
53036
|
|
|
53036
|
|
96742
|
my ( $self, $code ) = @_; |
86
|
|
|
|
|
|
|
|
87
|
53036
|
|
|
|
|
188988
|
my ( $code_package, $code_name ) = Class::MOP::get_code_info($code); |
88
|
|
|
|
|
|
|
|
89
|
53036
|
|
66
|
|
|
352428
|
return ( $code_package && $code_package eq $self->name ) |
90
|
|
|
|
|
|
|
|| ( $code_package eq 'constant' && $code_name eq '__ANON__' ); |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
sub has_method { |
94
|
25683
|
|
|
25683
|
0
|
167926
|
my ( $self, $method_name ) = @_; |
95
|
|
|
|
|
|
|
|
96
|
25683
|
100
|
100
|
|
|
100297
|
( defined $method_name && length $method_name ) |
97
|
|
|
|
|
|
|
|| $self->_throw_exception( MustDefineAMethodName => instance => $self ); |
98
|
|
|
|
|
|
|
|
99
|
25679
|
|
|
|
|
59154
|
my $method = $self->_get_maybe_raw_method($method_name); |
100
|
25679
|
100
|
|
|
|
118397
|
return if not $method; |
101
|
|
|
|
|
|
|
|
102
|
1439
|
|
|
|
|
10430
|
return defined($self->_method_map->{$method_name} = $method); |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub get_method { |
106
|
269517
|
|
|
269517
|
0
|
523926
|
my ( $self, $method_name ) = @_; |
107
|
|
|
|
|
|
|
|
108
|
269517
|
100
|
100
|
|
|
817389
|
( defined $method_name && length $method_name ) |
109
|
|
|
|
|
|
|
|| $self->_throw_exception( MustDefineAMethodName => instance => $self ); |
110
|
|
|
|
|
|
|
|
111
|
269514
|
|
|
|
|
512819
|
my $method = $self->_get_maybe_raw_method($method_name); |
112
|
269514
|
100
|
|
|
|
725681
|
return if not $method; |
113
|
|
|
|
|
|
|
|
114
|
81353
|
100
|
100
|
|
|
443585
|
return $method if blessed($method) && $method->isa('Class::MOP::Method'); |
115
|
|
|
|
|
|
|
|
116
|
29250
|
|
|
|
|
72963
|
return $self->_method_map->{$method_name} = $self->wrap_method_body( |
117
|
|
|
|
|
|
|
body => $method, |
118
|
|
|
|
|
|
|
name => $method_name, |
119
|
|
|
|
|
|
|
associated_metaclass => $self, |
120
|
|
|
|
|
|
|
); |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub _get_maybe_raw_method { |
124
|
295193
|
|
|
295193
|
|
475256
|
my ( $self, $method_name ) = @_; |
125
|
|
|
|
|
|
|
|
126
|
295193
|
|
|
|
|
1097927
|
my $map_entry = $self->_method_map->{$method_name}; |
127
|
295193
|
100
|
|
|
|
643131
|
return $map_entry if defined $map_entry; |
128
|
|
|
|
|
|
|
|
129
|
241636
|
|
|
|
|
707745
|
my $code = $self->get_package_symbol("&$method_name"); |
130
|
|
|
|
|
|
|
|
131
|
241636
|
100
|
100
|
|
|
733982
|
return unless $code && $self->_code_is_mine($code); |
132
|
|
|
|
|
|
|
|
133
|
29235
|
|
|
|
|
61224
|
return $code; |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
sub remove_method { |
137
|
84
|
|
|
84
|
0
|
1381
|
my ( $self, $method_name ) = @_; |
138
|
|
|
|
|
|
|
|
139
|
84
|
100
|
100
|
|
|
468
|
( defined $method_name && length $method_name ) |
140
|
|
|
|
|
|
|
|| $self->_throw_exception( MustDefineAMethodName => instance => $self ); |
141
|
|
|
|
|
|
|
|
142
|
81
|
|
|
|
|
504
|
my $removed_method = delete $self->_method_map->{$method_name}; |
143
|
|
|
|
|
|
|
|
144
|
81
|
|
|
|
|
561
|
$self->remove_package_symbol("&$method_name"); |
145
|
|
|
|
|
|
|
|
146
|
81
|
100
|
66
|
|
|
1442
|
$removed_method->detach_from_class |
147
|
|
|
|
|
|
|
if blessed($removed_method) && $removed_method->isa('Class::MOP::Method'); |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
# still valid, since we just removed the method from the map |
150
|
81
|
|
|
|
|
302
|
$self->update_package_cache_flag; |
151
|
|
|
|
|
|
|
|
152
|
81
|
|
|
|
|
260
|
return $removed_method; |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub get_method_list { |
156
|
215
|
|
|
215
|
0
|
4301
|
my $self = shift; |
157
|
|
|
|
|
|
|
|
158
|
215
|
|
|
|
|
320
|
return keys %{ $self->_full_method_map }; |
|
215
|
|
|
|
|
672
|
|
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
sub _get_local_methods { |
162
|
7695
|
|
|
7695
|
|
14184
|
my $self = shift; |
163
|
|
|
|
|
|
|
|
164
|
7695
|
|
|
|
|
11662
|
return values %{ $self->_full_method_map }; |
|
7695
|
|
|
|
|
20674
|
|
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
sub _restore_metamethods_from { |
168
|
133
|
|
|
133
|
|
1613
|
my $self = shift; |
169
|
133
|
|
|
|
|
349
|
my ($old_meta) = @_; |
170
|
|
|
|
|
|
|
|
171
|
133
|
|
|
|
|
482
|
my $package_name = $self->name; |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
# Check if Perl debugger is enabled |
174
|
133
|
|
|
|
|
1246
|
my $debugger_enabled = ($^P & 0x10); |
175
|
133
|
|
|
|
|
585
|
my $debug_method_info; |
176
|
|
|
|
|
|
|
|
177
|
133
|
|
|
|
|
552
|
for my $method ($old_meta->_get_local_methods) { |
178
|
164
|
|
|
|
|
699
|
my $method_name = $method->name; |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
# Track DB::sub information for this method if debugger is enabled. |
181
|
|
|
|
|
|
|
# This contains original method filename and line numbers. |
182
|
164
|
|
|
|
|
323
|
$debug_method_info = ''; |
183
|
164
|
100
|
|
|
|
979
|
if ($debugger_enabled) { |
184
|
8
|
|
|
|
|
27
|
$debug_method_info = $DB::sub{$package_name . "::" . $method_name} |
185
|
|
|
|
|
|
|
} |
186
|
|
|
|
|
|
|
|
187
|
164
|
|
|
|
|
2021
|
$method->_make_compatible_with($self->method_metaclass); |
188
|
161
|
|
|
|
|
958
|
$self->add_method($method_name => $method); |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
# Restore method debug information, which can be clobbered by add_method. |
191
|
|
|
|
|
|
|
# Note that we handle this here instead of in add_method, because we |
192
|
|
|
|
|
|
|
# only want to preserve the original debug info in cases where we are |
193
|
|
|
|
|
|
|
# restoring a method, not overwriting a method. |
194
|
161
|
100
|
66
|
|
|
886
|
if ($debugger_enabled && $debug_method_info) { |
195
|
8
|
|
|
|
|
31
|
$DB::sub{$package_name . "::" . $method_name} = $debug_method_info; |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
} |
198
|
|
|
|
|
|
|
} |
199
|
|
|
|
|
|
|
|
200
|
1584
|
|
|
1584
|
0
|
7895
|
sub reset_package_cache_flag { (shift)->{'_package_cache_flag'} = undef } |
201
|
|
|
|
|
|
|
sub update_package_cache_flag { |
202
|
179245
|
|
|
179245
|
0
|
287813
|
my $self = shift; |
203
|
|
|
|
|
|
|
# NOTE: |
204
|
|
|
|
|
|
|
# we can manually update the cache number |
205
|
|
|
|
|
|
|
# since we are actually adding the method |
206
|
|
|
|
|
|
|
# to our cache as well. This avoids us |
207
|
|
|
|
|
|
|
# having to regenerate the method_map. |
208
|
|
|
|
|
|
|
# - SL |
209
|
179245
|
|
|
|
|
1348018
|
$self->{'_package_cache_flag'} = Class::MOP::check_package_cache_flag($self->name); |
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
sub _full_method_map { |
213
|
7910
|
|
|
7910
|
|
12914
|
my $self = shift; |
214
|
|
|
|
|
|
|
|
215
|
7910
|
|
|
|
|
30025
|
my $pkg_gen = Class::MOP::check_package_cache_flag($self->name); |
216
|
|
|
|
|
|
|
|
217
|
7910
|
100
|
100
|
|
|
36186
|
if (($self->{_package_cache_flag_full} || -1) != $pkg_gen) { |
218
|
|
|
|
|
|
|
# forcibly reify all method map entries |
219
|
|
|
|
|
|
|
$self->get_method($_) |
220
|
3424
|
|
|
|
|
15452
|
for $self->list_all_package_symbols('CODE'); |
221
|
3424
|
|
|
|
|
13485
|
$self->{_package_cache_flag_full} = $pkg_gen; |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
|
224
|
7910
|
|
|
|
|
91085
|
return $self->_method_map; |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
1; |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
# ABSTRACT: Methods for metaclasses which have methods |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
__END__ |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
=pod |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
=encoding UTF-8 |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
=head1 NAME |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
Class::MOP::Mixin::HasMethods - Methods for metaclasses which have methods |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
=head1 VERSION |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
version 2.2206 |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=head1 DESCRIPTION |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
This class implements methods for metaclasses which have methods |
248
|
|
|
|
|
|
|
(L<Class::MOP::Class> and L<Moose::Meta::Role>). See L<Class::MOP::Class> for |
249
|
|
|
|
|
|
|
API details. |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
=head1 AUTHORS |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
=over 4 |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
=item * |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
Stevan Little <stevan@cpan.org> |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
=item * |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
Dave Rolsky <autarch@urth.org> |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
=item * |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
Jesse Luehrs <doy@cpan.org> |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
=item * |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
Shawn M Moore <sartak@cpan.org> |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
=item * |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org> |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
=item * |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
Karen Etheridge <ether@cpan.org> |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
=item * |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
Florian Ragwitz <rafl@debian.org> |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
=item * |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
Hans Dieter Pearcey <hdp@cpan.org> |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
=item * |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
Chris Prather <chris@prather.org> |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
=item * |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
Matt S Trout <mstrout@cpan.org> |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=back |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
This software is copyright (c) 2006 by Infinity Interactive, Inc. |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
302
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
=cut |