← Index
NYTProf Performance Profile   « block view • line view • sub view »
For 01.HTTP.t
  Run on Tue May 4 15:25:55 2010
Reported on Tue May 4 15:26:05 2010

File /usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Moose/Meta/Class.pm
Statements Executed 219
Statement Execution Time 4.19ms
Subroutines — ordered by exclusive time
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1111.34ms1.51msMoose::Meta::Class::::BEGIN@22Moose::Meta::Class::BEGIN@22
1111.18ms1.36msMoose::Meta::Class::::BEGIN@23Moose::Meta::Class::BEGIN@23
111911µs2.03msMoose::Meta::Class::::BEGIN@18Moose::Meta::Class::BEGIN@18
111876µs10.9msMoose::Meta::Class::::BEGIN@20Moose::Meta::Class::BEGIN@20
111369µs453µsMoose::Meta::Class::::BEGIN@19Moose::Meta::Class::BEGIN@19
111270µs368µsMoose::Meta::Class::::BEGIN@21Moose::Meta::Class::BEGIN@21
2484123µs1.85msMoose::Meta::Class::::initializeMoose::Meta::Class::initialize
41197µs4.97msMoose::Meta::Class::::add_attributeMoose::Meta::Class::add_attribute
41160µs1.35msMoose::Meta::Class::::_process_new_attributeMoose::Meta::Class::_process_new_attribute
52255µs358µsMoose::Meta::Class::::superclassesMoose::Meta::Class::superclasses
41143µs1.39msMoose::Meta::Class::::_process_attributeMoose::Meta::Class::_process_attribute
32138µs287µsMoose::Meta::Class::::_check_metaclass_compatibilityMoose::Meta::Class::_check_metaclass_compatibility
11134µs42µsMoose::Meta::Class::::_superclass_meta_is_compatibleMoose::Meta::Class::_superclass_meta_is_compatible
11116µs19µsMoose::Meta::Class::::BEGIN@4Moose::Meta::Class::BEGIN@4
11113µs67µsMoose::Meta::Class::::_fix_metaclass_incompatibilityMoose::Meta::Class::_fix_metaclass_incompatibility
11111µs45µsMoose::Meta::Class::::_immutable_optionsMoose::Meta::Class::_immutable_options
1117µs16µsMoose::Meta::Class::::BEGIN@5Moose::Meta::Class::BEGIN@5
1117µs53µsMoose::Meta::Class::::BEGIN@25Moose::Meta::Class::BEGIN@25
1117µs48µsMoose::Meta::Class::::_fix_one_incompatible_metaclassMoose::Meta::Class::_fix_one_incompatible_metaclass
1117µs40µsMoose::Meta::Class::::BEGIN@11Moose::Meta::Class::BEGIN@11
1116µs33µsMoose::Meta::Class::::BEGIN@10Moose::Meta::Class::BEGIN@10
1116µs32µsMoose::Meta::Class::::BEGIN@12Moose::Meta::Class::BEGIN@12
2115µs5µsMoose::Meta::Class::::__ANON__[:34]Moose::Meta::Class::__ANON__[:34]
2115µs5µsMoose::Meta::Class::::__ANON__[:29]Moose::Meta::Class::__ANON__[:29]
1114µs4µsMoose::Meta::Class::::BEGIN@7Moose::Meta::Class::BEGIN@7
1114µs4µsMoose::Meta::Class::::BEGIN@9Moose::Meta::Class::BEGIN@9
4123µs3µsMoose::Meta::Class::::CORE:matchMoose::Meta::Class::CORE:match (opcode)
0000s0sMoose::Meta::Class::::__ANON__[:407]Moose::Meta::Class::__ANON__[:407]
0000s0sMoose::Meta::Class::::__ANON__[:493]Moose::Meta::Class::__ANON__[:493]
0000s0sMoose::Meta::Class::::__ANON__[:526]Moose::Meta::Class::__ANON__[:526]
0000s0sMoose::Meta::Class::::_all_metaclasses_differ_by_roles_onlyMoose::Meta::Class::_all_metaclasses_differ_by_roles_only
0000s0sMoose::Meta::Class::::_all_rolesMoose::Meta::Class::_all_roles
0000s0sMoose::Meta::Class::::_all_roles_untilMoose::Meta::Class::_all_roles_until
0000s0sMoose::Meta::Class::::_anon_cache_keyMoose::Meta::Class::_anon_cache_key
0000s0sMoose::Meta::Class::::_find_common_ancestorMoose::Meta::Class::_find_common_ancestor
0000s0sMoose::Meta::Class::::_find_next_method_by_name_which_is_not_overriddenMoose::Meta::Class::_find_next_method_by_name_which_is_not_overridden
0000s0sMoose::Meta::Class::::_is_role_only_subclass_ofMoose::Meta::Class::_is_role_only_subclass_of
0000s0sMoose::Meta::Class::::_process_inherited_attributeMoose::Meta::Class::_process_inherited_attribute
0000s0sMoose::Meta::Class::::_reconcile_role_differencesMoose::Meta::Class::_reconcile_role_differences
0000s0sMoose::Meta::Class::::_reconcile_with_superclass_metaMoose::Meta::Class::_reconcile_with_superclass_meta
0000s0sMoose::Meta::Class::::_reinitialize_withMoose::Meta::Class::_reinitialize_with
0000s0sMoose::Meta::Class::::add_augment_method_modifierMoose::Meta::Class::add_augment_method_modifier
0000s0sMoose::Meta::Class::::add_override_method_modifierMoose::Meta::Class::add_override_method_modifier
0000s0sMoose::Meta::Class::::add_roleMoose::Meta::Class::add_role
0000s0sMoose::Meta::Class::::add_role_applicationMoose::Meta::Class::add_role_application
0000s0sMoose::Meta::Class::::calculate_all_rolesMoose::Meta::Class::calculate_all_roles
0000s0sMoose::Meta::Class::::createMoose::Meta::Class::create
0000s0sMoose::Meta::Class::::create_anon_classMoose::Meta::Class::create_anon_class
0000s0sMoose::Meta::Class::::create_errorMoose::Meta::Class::create_error
0000s0sMoose::Meta::Class::::does_roleMoose::Meta::Class::does_role
0000s0sMoose::Meta::Class::::excludes_roleMoose::Meta::Class::excludes_role
0000s0sMoose::Meta::Class::::new_objectMoose::Meta::Class::new_object
0000s0sMoose::Meta::Class::::raise_errorMoose::Meta::Class::raise_error
0000s0sMoose::Meta::Class::::reinitializeMoose::Meta::Class::reinitialize
0000s0sMoose::Meta::Class::::role_applicationsMoose::Meta::Class::role_applications
0000s0sMoose::Meta::Class::::throw_errorMoose::Meta::Class::throw_error
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1
2package Moose::Meta::Class;
3
4322µs222µs
# spent 19µs (16+3) within Moose::Meta::Class::BEGIN@4 which was called # once (16µs+3µs) by Moose::BEGIN@18 at line 4
use strict;
# spent 19µs making 1 call to Moose::Meta::Class::BEGIN@4 # spent 3µs making 1 call to strict::import
5320µs226µs
# spent 16µs (7+9) within Moose::Meta::Class::BEGIN@5 which was called # once (7µs+9µs) by Moose::BEGIN@18 at line 5
use warnings;
# spent 16µs making 1 call to Moose::Meta::Class::BEGIN@5 # spent 9µs making 1 call to warnings::import
6
7322µs14µs
# spent 4µs within Moose::Meta::Class::BEGIN@7 which was called # once (4µs+0s) by Moose::BEGIN@18 at line 7
use Class::MOP;
# spent 4µs making 1 call to Moose::Meta::Class::BEGIN@7
8
9319µs14µs
# spent 4µs within Moose::Meta::Class::BEGIN@9 which was called # once (4µs+0s) by Moose::BEGIN@18 at line 9
use Carp ();
# spent 4µs making 1 call to Moose::Meta::Class::BEGIN@9
10324µs259µs
# spent 33µs (6+26) within Moose::Meta::Class::BEGIN@10 which was called # once (6µs+26µs) by Moose::BEGIN@18 at line 10
use List::Util qw( first );
# spent 33µs making 1 call to Moose::Meta::Class::BEGIN@10 # spent 26µs making 1 call to Exporter::import
11323µs273µs
# spent 40µs (7+33) within Moose::Meta::Class::BEGIN@11 which was called # once (7µs+33µs) by Moose::BEGIN@18 at line 11
use List::MoreUtils qw( any all uniq first_index );
# spent 40µs making 1 call to Moose::Meta::Class::BEGIN@11 # spent 33µs making 1 call to Exporter::import
12349µs257µs
# spent 32µs (6+25) within Moose::Meta::Class::BEGIN@12 which was called # once (6µs+25µs) by Moose::BEGIN@18 at line 12
use Scalar::Util 'weaken', 'blessed';
# spent 32µs making 1 call to Moose::Meta::Class::BEGIN@12 # spent 25µs making 1 call to Exporter::import
13
141800nsour $VERSION = '0.98';
15114µs$VERSION = eval $VERSION;
161600nsour $AUTHORITY = 'cpan:STEVAN';
17
183142µs12.03ms
# spent 2.03ms (911µs+1.12) within Moose::Meta::Class::BEGIN@18 which was called # once (911µs+1.12ms) by Moose::BEGIN@18 at line 18
use Moose::Meta::Method::Overridden;
# spent 2.03ms making 1 call to Moose::Meta::Class::BEGIN@18
193156µs1453µs
# spent 453µs (369+84) within Moose::Meta::Class::BEGIN@19 which was called # once (369µs+84µs) by Moose::BEGIN@18 at line 19
use Moose::Meta::Method::Augmented;
# spent 453µs making 1 call to Moose::Meta::Class::BEGIN@19
203114µs110.9ms
# spent 10.9ms (876µs+10.0) within Moose::Meta::Class::BEGIN@20 which was called # once (876µs+10.0ms) by Moose::BEGIN@18 at line 20
use Moose::Error::Default;
# spent 10.9ms making 1 call to Moose::Meta::Class::BEGIN@20
213112µs1368µs
# spent 368µs (270+98) within Moose::Meta::Class::BEGIN@21 which was called # once (270µs+98µs) by Moose::BEGIN@18 at line 21
use Moose::Meta::Class::Immutable::Trait;
# spent 368µs making 1 call to Moose::Meta::Class::BEGIN@21
223106µs11.51ms
# spent 1.51ms (1.34+170µs) within Moose::Meta::Class::BEGIN@22 which was called # once (1.34ms+170µs) by Moose::BEGIN@18 at line 22
use Moose::Meta::Method::Constructor;
# spent 1.51ms making 1 call to Moose::Meta::Class::BEGIN@22
233705µs11.36ms
# spent 1.36ms (1.18+173µs) within Moose::Meta::Class::BEGIN@23 which was called # once (1.18ms+173µs) by Moose::BEGIN@18 at line 23
use Moose::Meta::Method::Destructor;
# spent 1.36ms making 1 call to Moose::Meta::Class::BEGIN@23
24
2532.15ms299µs
# spent 53µs (7+46) within Moose::Meta::Class::BEGIN@25 which was called # once (7µs+46µs) by Moose::BEGIN@18 at line 25
use base 'Class::MOP::Class';
# spent 53µs making 1 call to Moose::Meta::Class::BEGIN@25 # spent 46µs making 1 call to base::import
26
27__PACKAGE__->meta->add_attribute('roles' => (
28 reader => 'roles',
2927µs
# spent 5µs within Moose::Meta::Class::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Moose/Meta/Class.pm:29] which was called 2 times, avg 2µs/call: # 2 times (5µs+0s) by Class::MOP::Mixin::AttributeCore::default at line 53 of Class/MOP/Mixin/AttributeCore.pm, avg 2µs/call
default => sub { [] }
30120µs2690µs));
# spent 597µs making 1 call to Class::MOP::Mixin::HasAttributes::add_attribute # spent 93µs making 1 call to Class::MOP::Object::meta
31
32__PACKAGE__->meta->add_attribute('role_applications' => (
33 reader => '_get_role_applications',
3426µs
# spent 5µs within Moose::Meta::Class::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Moose/Meta/Class.pm:34] which was called 2 times, avg 3µs/call: # 2 times (5µs+0s) by Class::MOP::Mixin::AttributeCore::default at line 53 of Class/MOP/Mixin/AttributeCore.pm, avg 3µs/call
default => sub { [] }
3514µs2266µs));
# spent 255µs making 1 call to Class::MOP::Mixin::HasAttributes::add_attribute # spent 11µs making 1 call to Class::MOP::Object::meta
36
3714µs3288µs__PACKAGE__->meta->add_attribute(
# spent 259µs making 1 call to Class::MOP::Mixin::HasAttributes::add_attribute # spent 18µs making 1 call to Class::MOP::Attribute::new # spent 11µs making 1 call to Class::MOP::Object::meta
38 Class::MOP::Attribute->new('immutable_trait' => (
39 accessor => "immutable_trait",
40 default => 'Moose::Meta::Class::Immutable::Trait',
41 ))
42);
43
4412µs2267µs__PACKAGE__->meta->add_attribute('constructor_class' => (
# spent 256µs making 1 call to Class::MOP::Mixin::HasAttributes::add_attribute # spent 11µs making 1 call to Class::MOP::Object::meta
45 accessor => 'constructor_class',
46 default => 'Moose::Meta::Method::Constructor',
47));
48
4912µs2259µs__PACKAGE__->meta->add_attribute('destructor_class' => (
# spent 248µs making 1 call to Class::MOP::Mixin::HasAttributes::add_attribute # spent 11µs making 1 call to Class::MOP::Object::meta
50 accessor => 'destructor_class',
51 default => 'Moose::Meta::Method::Destructor',
52));
53
5412µs2278µs__PACKAGE__->meta->add_attribute('error_class' => (
# spent 267µs making 1 call to Class::MOP::Mixin::HasAttributes::add_attribute # spent 11µs making 1 call to Class::MOP::Object::meta
55 accessor => 'error_class',
56 default => 'Moose::Error::Default',
57));
58
59
# spent 1.85ms (123µs+1.72) within Moose::Meta::Class::initialize which was called 24 times, avg 77µs/call: # 10 times (39µs+10µs) by Class::MOP::Class::get_all_attributes at line 551 of Class/MOP/Class.pm, avg 5µs/call # 4 times (13µs+4µs) by Class::MOP::Class::find_method_by_name at line 729 of Class/MOP/Class.pm, avg 4µs/call # 4 times (13µs+4µs) by Class::MOP::Class::find_all_methods_by_name at line 762 of Class/MOP/Class.pm, avg 4µs/call # 2 times (6µs+2µs) by Class::MOP::Class::find_next_method_by_name at line 779 of Class/MOP/Class.pm, avg 4µs/call # once (29µs+931µs) by metaclass::import at line 43 of metaclass.pm # once (15µs+772µs) by Moose::init_meta at line 194 of Moose.pm # once (4µs+1µs) by SimpleDB::Client::meta at line 220 of Moose.pm # once (4µs+1µs) by Moose::Meta::Class::_fix_metaclass_incompatibility at line 349
sub initialize {
6072113µs my $class = shift;
61 my $pkg = shift;
62 return Class::MOP::get_metaclass_by_name($pkg)
# spent 1.70ms making 2 calls to Class::MOP::Class::initialize, avg 850µs/call # spent 24µs making 24 calls to Class::MOP::get_metaclass_by_name, avg 1µs/call
63 || $class->SUPER::initialize($pkg,
64 'attribute_metaclass' => 'Moose::Meta::Attribute',
65 'method_metaclass' => 'Moose::Meta::Method',
66 'instance_metaclass' => 'Moose::Meta::Instance',
67 @_
68 );
69}
70
71
# spent 45µs (11+34) within Moose::Meta::Class::_immutable_options which was called # once (11µs+34µs) by Class::MOP::Class::make_immutable at line 892 of Class/MOP/Class.pm
sub _immutable_options {
72210µs my ( $self, @args ) = @_;
73
74 $self->SUPER::_immutable_options(
# spent 34µs making 1 call to Class::MOP::Class::_immutable_options
75 inline_destructor => 1,
76
77 # Moose always does this when an attribute is created
78 inline_accessors => 0,
79
80 @args,
81 );
82}
83
84sub create {
85 my ($self, $package_name, %options) = @_;
86
87 (ref $options{roles} eq 'ARRAY')
88 || $self->throw_error("You must pass an ARRAY ref of roles", data => $options{roles})
89 if exists $options{roles};
90 my $roles = delete $options{roles};
91
92 my $class = $self->SUPER::create($package_name, %options);
93
94 if ($roles) {
95 Moose::Util::apply_all_roles( $class, @$roles );
96 }
97
98 return $class;
99}
100
101
# spent 287µs (38+249) within Moose::Meta::Class::_check_metaclass_compatibility which was called 3 times, avg 96µs/call: # 2 times (26µs+126µs) by Class::MOP::Class::_construct_class_instance at line 91 of Class/MOP/Class.pm, avg 76µs/call # once (12µs+123µs) by Class::MOP::Class::superclasses at line 579 of Class/MOP/Class.pm
sub _check_metaclass_compatibility {
102933µs my $self = shift;
103
104 if ( my @supers = $self->superclasses ) {
# spent 106µs making 3 calls to Moose::Meta::Class::superclasses, avg 35µs/call, recursion: max depth 1, time 21µs # spent 67µs making 1 call to Moose::Meta::Class::_fix_metaclass_incompatibility
105 $self->_fix_metaclass_incompatibility(@supers);
106 }
107
108 $self->SUPER::_check_metaclass_compatibility(@_);
# spent 76µs making 3 calls to Class::MOP::Class::_check_metaclass_compatibility, avg 25µs/call
109}
110
1111100nsmy %ANON_CLASSES;
112
113sub create_anon_class {
114 my ($self, %options) = @_;
115
116 my $cache_ok = delete $options{cache};
117
118 my $cache_key
119 = _anon_cache_key( $options{superclasses}, $options{roles} );
120
121 if ($cache_ok && defined $ANON_CLASSES{$cache_key}) {
122 return $ANON_CLASSES{$cache_key};
123 }
124
125 my $new_class = $self->SUPER::create_anon_class(%options);
126
127 $ANON_CLASSES{$cache_key} = $new_class
128 if $cache_ok;
129
130 return $new_class;
131}
132
133sub _anon_cache_key {
134 # Makes something like Super::Class|Super::Class::2=Role|Role::1
135 return join '=' => (
136 join( '|', @{ $_[0] || [] } ),
137 join( '|', sort @{ $_[1] || [] } ),
138 );
139}
140
141sub reinitialize {
142 my $self = shift;
143 my $pkg = shift;
144
145 my $meta = blessed $pkg ? $pkg : Class::MOP::class_of($pkg);
146
147 my $cache_key;
148
149 my %existing_classes;
150 if ($meta) {
151 %existing_classes = map { $_ => $meta->$_() } qw(
152 attribute_metaclass
153 method_metaclass
154 wrapped_method_metaclass
155 instance_metaclass
156 constructor_class
157 destructor_class
158 error_class
159 );
160
161 $cache_key = _anon_cache_key(
162 [ $meta->superclasses ],
163 [ map { $_->name } @{ $meta->roles } ],
164 ) if $meta->is_anon_class;
165 }
166
167 my $new_meta = $self->SUPER::reinitialize(
168 $pkg,
169 %existing_classes,
170 @_,
171 );
172
173 return $new_meta unless defined $cache_key;
174
175 my $new_cache_key = _anon_cache_key(
176 [ $meta->superclasses ],
177 [ map { $_->name } @{ $meta->roles } ],
178 );
179
180 delete $ANON_CLASSES{$cache_key};
181 $ANON_CLASSES{$new_cache_key} = $new_meta;
182
183 return $new_meta;
184}
185
186sub add_role {
187 my ($self, $role) = @_;
188 (blessed($role) && $role->isa('Moose::Meta::Role'))
189 || $self->throw_error("Roles must be instances of Moose::Meta::Role", data => $role);
190 push @{$self->roles} => $role;
191}
192
193sub role_applications {
194 my ($self) = @_;
195
196 return @{$self->_get_role_applications};
197}
198
199sub add_role_application {
200 my ($self, $application) = @_;
201 (blessed($application) && $application->isa('Moose::Meta::Role::Application::ToClass'))
202 || $self->throw_error("Role applications must be instances of Moose::Meta::Role::Application::ToClass", data => $application);
203 push @{$self->_get_role_applications} => $application;
204}
205
206sub calculate_all_roles {
207 my $self = shift;
208 my %seen;
209 grep { !$seen{$_->name}++ } map { $_->calculate_all_roles } @{ $self->roles };
210}
211
212sub does_role {
213 my ($self, $role_name) = @_;
214
215 (defined $role_name)
216 || $self->throw_error("You must supply a role name to look for");
217
218 foreach my $class ($self->class_precedence_list) {
219 my $meta = Class::MOP::class_of($class);
220 # when a Moose metaclass is itself extended with a role,
221 # this check needs to be done since some items in the
222 # class_precedence_list might in fact be Class::MOP
223 # based still.
224 next unless $meta && $meta->can('roles');
225 foreach my $role (@{$meta->roles}) {
226 return 1 if $role->does_role($role_name);
227 }
228 }
229 return 0;
230}
231
232sub excludes_role {
233 my ($self, $role_name) = @_;
234
235 (defined $role_name)
236 || $self->throw_error("You must supply a role name to look for");
237
238 foreach my $class ($self->class_precedence_list) {
239 my $meta = Class::MOP::class_of($class);
240 # when a Moose metaclass is itself extended with a role,
241 # this check needs to be done since some items in the
242 # class_precedence_list might in fact be Class::MOP
243 # based still.
244 next unless $meta && $meta->can('roles');
245 foreach my $role (@{$meta->roles}) {
246 return 1 if $role->excludes_role($role_name);
247 }
248 }
249 return 0;
250}
251
252sub new_object {
253 my $class = shift;
254 my $params = @_ == 1 ? $_[0] : {@_};
255 my $self = $class->SUPER::new_object($params);
256
257 foreach my $attr ( $class->get_all_attributes() ) {
258
259 next unless $attr->can('has_trigger') && $attr->has_trigger;
260
261 my $init_arg = $attr->init_arg;
262
263 next unless defined $init_arg;
264
265 next unless exists $params->{$init_arg};
266
267 $attr->trigger->(
268 $self,
269 (
270 $attr->should_coerce
271 ? $attr->get_read_method_ref->($self)
272 : $params->{$init_arg}
273 ),
274 );
275 }
276
277 return $self;
278}
279
280
# spent 358µs (55+303) within Moose::Meta::Class::superclasses which was called 5 times, avg 72µs/call: # 3 times (31µs+54µs) by Moose::Meta::Class::_check_metaclass_compatibility at line 104, avg 28µs/call # 2 times (24µs+249µs) by Moose::init_meta at line 226 of Moose.pm, avg 136µs/call
sub superclasses {
2812351µs my $self = shift;
282 my @supers = @_;
283 foreach my $super (@supers) {
284 Class::MOP::load_class($super);
# spent 35µs making 1 call to Class::MOP::load_class
285 my $meta = Class::MOP::class_of($super);
# spent 8µs making 1 call to Class::MOP::class_of
286 $self->throw_error("You cannot inherit from a Moose Role ($super)")
# spent 2µs making 1 call to UNIVERSAL::isa
287 if $meta && $meta->isa('Moose::Meta::Role')
288 }
289 return $self->SUPER::superclasses(@supers);
# spent 280µs making 5 calls to Class::MOP::Class::superclasses, avg 56µs/call, recursion: max depth 1, time 13µs
290}
291
292### ---------------------------------------------
293
294
# spent 4.97ms (97µs+4.87) within Moose::Meta::Class::add_attribute which was called 4 times, avg 1.24ms/call: # 4 times (97µs+4.87ms) by Moose::has at line 69 of Moose.pm, avg 1.24ms/call
sub add_attribute {
2952094µs my $self = shift;
296 my $attr =
# spent 1.39ms making 4 calls to Moose::Meta::Class::_process_attribute, avg 348µs/call # spent 2µs making 4 calls to Scalar::Util::blessed, avg 600ns/call
297 (blessed $_[0] && $_[0]->isa('Class::MOP::Attribute')
298 ? $_[0]
299 : $self->_process_attribute(@_));
300 $self->SUPER::add_attribute($attr);
# spent 3.45ms making 4 calls to Class::MOP::Mixin::HasAttributes::add_attribute, avg 862µs/call
301 # it may be a Class::MOP::Attribute, theoretically, which doesn't have
302 # 'bare' and doesn't implement this method
303 if ($attr->can('_check_associated_methods')) {
# spent 26µs making 4 calls to Moose::Meta::Attribute::_check_associated_methods, avg 6µs/call # spent 6µs making 4 calls to UNIVERSAL::can, avg 1µs/call
304 $attr->_check_associated_methods;
305 }
306 return $attr;
307}
308
309sub add_override_method_modifier {
310 my ($self, $name, $method, $_super_package) = @_;
311
312 (!$self->has_method($name))
313 || $self->throw_error("Cannot add an override method if a local method is already present");
314
315 $self->add_method($name => Moose::Meta::Method::Overridden->new(
316 method => $method,
317 class => $self,
318 package => $_super_package, # need this for roles
319 name => $name,
320 ));
321}
322
323sub add_augment_method_modifier {
324 my ($self, $name, $method) = @_;
325 (!$self->has_method($name))
326 || $self->throw_error("Cannot add an augment method if a local method is already present");
327
328 $self->add_method($name => Moose::Meta::Method::Augmented->new(
329 method => $method,
330 class => $self,
331 name => $name,
332 ));
333}
334
335## Private Utility methods ...
336
337sub _find_next_method_by_name_which_is_not_overridden {
338 my ($self, $name) = @_;
339 foreach my $method ($self->find_all_methods_by_name($name)) {
340 return $method->{code}
341 if blessed($method->{code}) && !$method->{code}->isa('Moose::Meta::Method::Overridden');
342 }
343 return undef;
344}
345
346
# spent 67µs (13+53) within Moose::Meta::Class::_fix_metaclass_incompatibility which was called # once (13µs+53µs) by Moose::Meta::Class::_check_metaclass_compatibility at line 104
sub _fix_metaclass_incompatibility {
347411µs my ($self, @superclasses) = @_;
348
349 $self->_fix_one_incompatible_metaclass($_)
# spent 5µs making 1 call to Moose::Meta::Class::initialize
350 for map { Moose::Meta::Class->initialize($_) } @superclasses;
351}
352
353
# spent 48µs (7+42) within Moose::Meta::Class::_fix_one_incompatible_metaclass which was called # once (7µs+42µs) by Moose::Meta::Class::_fix_metaclass_incompatibility at line 350
sub _fix_one_incompatible_metaclass {
35425µs my ($self, $meta) = @_;
355
356 return if $self->_superclass_meta_is_compatible($meta);
357
358 unless ( $self->is_pristine ) {
359 $self->throw_error(
360 "Cannot attempt to reinitialize metaclass for "
361 . $self->name
362 . ", it isn't pristine" );
363 }
364
365 $self->_reconcile_with_superclass_meta($meta);
366}
367
368
# spent 42µs (34+8) within Moose::Meta::Class::_superclass_meta_is_compatible which was called # once (34µs+8µs) by Moose::Meta::Class::_fix_one_incompatible_metaclass at line 356
sub _superclass_meta_is_compatible {
369428µs my ($self, $super_meta) = @_;
370
371 next unless $super_meta->isa("Class::MOP::Class");
# spent 900ns making 1 call to UNIVERSAL::isa
372
373 my $super_meta_name
# spent 1µs making 1 call to Class::MOP::Class::is_immutable
374 = $super_meta->is_immutable
375 ? $super_meta->_get_mutable_metaclass_name
376 : ref($super_meta);
377
378 return 1
# spent 3µs making 2 calls to UNIVERSAL::isa, avg 1µs/call # spent 3µs making 2 calls to Class::MOP::Class::instance_metaclass, avg 1µs/call
379 if $self->isa($super_meta_name)
380 and
381 $self->instance_metaclass->isa( $super_meta->instance_metaclass );
382}
383
384# I don't want to have to type this >1 time
38512µsmy @MetaClassTypes =
386 qw( attribute_metaclass
387 method_metaclass
388 wrapped_method_metaclass
389 instance_metaclass
390 constructor_class
391 destructor_class
392 error_class );
393
394sub _reconcile_with_superclass_meta {
395 my ($self, $super_meta) = @_;
396
397 my $super_meta_name
398 = $super_meta->is_immutable
399 ? $super_meta->_get_mutable_metaclass_name
400 : ref($super_meta);
401
402 my $self_metaclass = ref $self;
403
404 # If neither of these is true we have a more serious
405 # incompatibility that we just cannot fix (yet?).
406 if ( $super_meta_name->isa( ref $self )
407 && all { $super_meta->$_->isa( $self->$_ ) } @MetaClassTypes ) {
408 $self->_reinitialize_with($super_meta);
409 }
410 elsif ( $self->_all_metaclasses_differ_by_roles_only($super_meta) ) {
411 $self->_reconcile_role_differences($super_meta);
412 }
413}
414
415sub _reinitialize_with {
416 my ( $self, $new_meta ) = @_;
417
418 my $new_self = $new_meta->reinitialize(
419 $self->name,
420 attribute_metaclass => $new_meta->attribute_metaclass,
421 method_metaclass => $new_meta->method_metaclass,
422 instance_metaclass => $new_meta->instance_metaclass,
423 );
424
425 $new_self->$_( $new_meta->$_ )
426 for qw( constructor_class destructor_class error_class );
427
428 %$self = %$new_self;
429
430 bless $self, ref $new_self;
431
432 # We need to replace the cached metaclass instance or else when it
433 # goes out of scope Class::MOP::Class destroy's the namespace for
434 # the metaclass's class, causing much havoc.
435 Class::MOP::store_metaclass_by_name( $self->name, $self );
436 Class::MOP::weaken_metaclass( $self->name ) if $self->is_anon_class;
437}
438
439# In the more complex case, we share a common ancestor with our
440# superclass's metaclass, but each metaclass (ours and the parent's)
441# has a different set of roles applied. We reconcile this by first
442# reinitializing into the parent class, and _then_ applying our own
443# roles.
444sub _all_metaclasses_differ_by_roles_only {
445 my ($self, $super_meta) = @_;
446
447 for my $pair (
448 [ ref $self, ref $super_meta ],
449 map { [ $self->$_, $super_meta->$_ ] } @MetaClassTypes
450 ) {
451
452 next if $pair->[0] eq $pair->[1];
453
454 my $self_meta_meta = Class::MOP::Class->initialize( $pair->[0] );
455 my $super_meta_meta = Class::MOP::Class->initialize( $pair->[1] );
456
457 my $common_ancestor
458 = _find_common_ancestor( $self_meta_meta, $super_meta_meta );
459
460 return unless $common_ancestor;
461
462 return
463 unless _is_role_only_subclass_of(
464 $self_meta_meta,
465 $common_ancestor,
466 )
467 && _is_role_only_subclass_of(
468 $super_meta_meta,
469 $common_ancestor,
470 );
471 }
472
473 return 1;
474}
475
476# This, and some other functions, could be called as methods, but
477# they're not for two reasons. One, we just end up ignoring the first
478# argument, because we can't call these directly on one of the real
479# arguments, because one of them could be a Class::MOP::Class object
480# and not a Moose::Meta::Class. Second, only a completely insane
481# person would attempt to subclass this stuff!
482sub _find_common_ancestor {
483 my ($meta1, $meta2) = @_;
484
485 # FIXME? This doesn't account for multiple inheritance (not sure
486 # if it needs to though). For example, is somewhere in $meta1's
487 # history it inherits from both ClassA and ClassB, and $meta2
488 # inherits from ClassB & ClassA, does it matter? And what crazy
489 # fool would do that anyway?
490
491 my %meta1_parents = map { $_ => 1 } $meta1->linearized_isa;
492
493 return first { $meta1_parents{$_} } $meta2->linearized_isa;
494}
495
496sub _is_role_only_subclass_of {
497 my ($meta, $ancestor) = @_;
498
499 return 1 if $meta->name eq $ancestor;
500
501 my @roles = _all_roles_until( $meta, $ancestor );
502
503 my %role_packages = map { $_->name => 1 } @roles;
504
505 my $ancestor_meta = Class::MOP::Class->initialize($ancestor);
506
507 my %shared_ancestors = map { $_ => 1 } $ancestor_meta->linearized_isa;
508
509 for my $method ( $meta->get_all_methods() ) {
510 next if $method->name eq 'meta';
511 next if $method->can('associated_attribute');
512
513 next
514 if $role_packages{ $method->original_package_name }
515 || $shared_ancestors{ $method->original_package_name };
516
517 return 0;
518 }
519
520 # FIXME - this really isn't right. Just because an attribute is
521 # defined in a role doesn't mean it isn't _also_ defined in the
522 # subclass.
523 for my $attr ( $meta->get_all_attributes ) {
524 next if $shared_ancestors{ $attr->associated_class->name };
525
526 next if any { $_->has_attribute( $attr->name ) } @roles;
527
528 return 0;
529 }
530
531 return 1;
532}
533
534sub _all_roles {
535 my $meta = shift;
536
537 return _all_roles_until($meta);
538}
539
540sub _all_roles_until {
541 my ($meta, $stop_at_class) = @_;
542
543 return unless $meta->can('calculate_all_roles');
544
545 my @roles = $meta->calculate_all_roles;
546
547 for my $class ( $meta->linearized_isa ) {
548 last if $stop_at_class && $stop_at_class eq $class;
549
550 my $meta = Class::MOP::Class->initialize($class);
551 last unless $meta->can('calculate_all_roles');
552
553 push @roles, $meta->calculate_all_roles;
554 }
555
556 return uniq @roles;
557}
558
559sub _reconcile_role_differences {
560 my ($self, $super_meta) = @_;
561
562 my $self_meta = Class::MOP::class_of($self);
563
564 my %roles;
565
566 if ( my @roles = map { $_->name } _all_roles($self_meta) ) {
567 $roles{metaclass_roles} = \@roles;
568 }
569
570 for my $thing (@MetaClassTypes) {
571 my $name = $self->$thing();
572
573 my $thing_meta = Class::MOP::Class->initialize($name);
574
575 my @roles = map { $_->name } _all_roles($thing_meta)
576 or next;
577
578 $roles{ $thing . '_roles' } = \@roles;
579 }
580
581 $self->_reinitialize_with($super_meta);
582
583 Moose::Util::MetaRole::apply_metaclass_roles(
584 for_class => $self->name,
585 %roles,
586 );
587
588 return $self;
589}
590
591
# spent 1.39ms (43µs+1.35) within Moose::Meta::Class::_process_attribute which was called 4 times, avg 348µs/call: # 4 times (43µs+1.35ms) by Moose::Meta::Class::add_attribute at line 296, avg 348µs/call
sub _process_attribute {
5921644µs my ( $self, $name, @args ) = @_;
593
594 @args = %{$args[0]} if scalar @args == 1 && ref($args[0]) eq 'HASH';
595
596 if (($name || '') =~ /^\+(.*)/) {
# spent 3µs making 4 calls to Moose::Meta::Class::CORE:match, avg 675ns/call
597 return $self->_process_inherited_attribute($1, @args);
598 }
599 else {
600 return $self->_process_new_attribute($name, @args);
# spent 1.35ms making 4 calls to Moose::Meta::Class::_process_new_attribute, avg 337µs/call
601 }
602}
603
604
# spent 1.35ms (60µs+1.29) within Moose::Meta::Class::_process_new_attribute which was called 4 times, avg 337µs/call: # 4 times (60µs+1.29ms) by Moose::Meta::Class::_process_attribute at line 600, avg 337µs/call
sub _process_new_attribute {
605853µs my ( $self, $name, @args ) = @_;
606
607 $self->attribute_metaclass->interpolate_class_and_new($name, @args);
# spent 1.28ms making 4 calls to Moose::Meta::Attribute::interpolate_class_and_new, avg 320µs/call # spent 8µs making 4 calls to Class::MOP::Mixin::HasAttributes::attribute_metaclass, avg 2µs/call
608}
609
610sub _process_inherited_attribute {
611 my ($self, $attr_name, %options) = @_;
612 my $inherited_attr = $self->find_attribute_by_name($attr_name);
613 (defined $inherited_attr)
614 || $self->throw_error("Could not find an attribute by the name of '$attr_name' to inherit from in ${\$self->name}", data => $attr_name);
615 if ($inherited_attr->isa('Moose::Meta::Attribute')) {
616 return $inherited_attr->clone_and_inherit_options(%options);
617 }
618 else {
619 # NOTE:
620 # kind of a kludge to handle Class::MOP::Attributes
621 return $inherited_attr->Moose::Meta::Attribute::clone_and_inherit_options(%options);
622 }
623}
624
625## -------------------------------------------------
626
6271100nsour $error_level;
628
629sub throw_error {
630 my ( $self, @args ) = @_;
631 local $error_level = ($error_level || 0) + 1;
632 $self->raise_error($self->create_error(@args));
633}
634
635sub raise_error {
636 my ( $self, @args ) = @_;
637 die @args;
638}
639
640sub create_error {
641 my ( $self, @args ) = @_;
642
643 require Carp::Heavy;
644
645 local $error_level = ($error_level || 0 ) + 1;
646
647 if ( @args % 2 == 1 ) {
648 unshift @args, "message";
649 }
650
651 my %args = ( metaclass => $self, last_error => $@, @args );
652
653 $args{depth} += $error_level;
654
655 my $class = ref $self ? $self->error_class : "Moose::Error::Default";
656
657 Class::MOP::load_class($class);
658
659 $class->new(
660 Carp::caller_info($args{depth}),
661 %args
662 );
663}
664
665125µs1;
666
667__END__
668
669=pod
670
671=head1 NAME
672
673Moose::Meta::Class - The Moose metaclass
674
675=head1 DESCRIPTION
676
677This class is a subclass of L<Class::MOP::Class> that provides
678additional Moose-specific functionality.
679
680To really understand this class, you will need to start with the
681L<Class::MOP::Class> documentation. This class can be understood as a
682set of additional features on top of the basic feature provided by
683that parent class.
684
685=head1 INHERITANCE
686
687C<Moose::Meta::Class> is a subclass of L<Class::MOP::Class>.
688
689=head1 METHODS
690
691=over 4
692
693=item B<< Moose::Meta::Class->initialize($package_name, %options) >>
694
695This overrides the parent's method in order to provide its own
696defaults for the C<attribute_metaclass>, C<instance_metaclass>, and
697C<method_metaclass> options.
698
699These all default to the appropriate Moose class.
700
701=item B<< Moose::Meta::Class->create($package_name, %options) >>
702
703This overrides the parent's method in order to accept a C<roles>
704option. This should be an array reference containing roles
705that the class does, each optionally followed by a hashref of options
706(C<-excludes> and C<-alias>).
707
708 my $metaclass = Moose::Meta::Class->create( 'New::Class', roles => [...] );
709
710=item B<< Moose::Meta::Class->create_anon_class >>
711
712This overrides the parent's method to accept a C<roles> option, just
713as C<create> does.
714
715It also accepts a C<cache> option. If this is true, then the anonymous
716class will be cached based on its superclasses and roles. If an
717existing anonymous class in the cache has the same superclasses and
718roles, it will be reused.
719
720 my $metaclass = Moose::Meta::Class->create_anon_class(
721 superclasses => ['Foo'],
722 roles => [qw/Some Roles Go Here/],
723 cache => 1,
724 );
725
726=item B<< $metaclass->make_immutable(%options) >>
727
728This overrides the parent's method to add a few options. Specifically,
729it uses the Moose-specific constructor and destructor classes, and
730enables inlining the destructor.
731
732Also, since Moose always inlines attributes, it sets the
733C<inline_accessors> option to false.
734
735=item B<< $metaclass->new_object(%params) >>
736
737This overrides the parent's method in order to add support for
738attribute triggers.
739
740=item B<< $metaclass->add_override_method_modifier($name, $sub) >>
741
742This adds an C<override> method modifier to the package.
743
744=item B<< $metaclass->add_augment_method_modifier($name, $sub) >>
745
746This adds an C<augment> method modifier to the package.
747
748=item B<< $metaclass->calculate_all_roles >>
749
750This will return a unique array of C<Moose::Meta::Role> instances
751which are attached to this class.
752
753=item B<< $metaclass->add_role($role) >>
754
755This takes a L<Moose::Meta::Role> object, and adds it to the class's
756list of roles. This I<does not> actually apply the role to the class.
757
758=item B<< $metaclass->role_applications >>
759
760Returns a list of L<Moose::Meta::Role::Application::ToClass>
761objects, which contain the arguments to role application.
762
763=item B<< $metaclass->add_role_application($application) >>
764
765This takes a L<Moose::Meta::Role::Application::ToClass> object, and
766adds it to the class's list of role applications. This I<does not>
767actually apply any role to the class; it is only for tracking role
768applications.
769
770=item B<< $metaclass->does_role($role) >>
771
772This returns a boolean indicating whether or not the class does the specified
773role. The role provided can be either a role name or a L<Moose::Meta::Role>
774object. This tests both the class and its parents.
775
776=item B<< $metaclass->excludes_role($role_name) >>
777
778A class excludes a role if it has already composed a role which
779excludes the named role. This tests both the class and its parents.
780
781=item B<< $metaclass->add_attribute($attr_name, %params|$params) >>
782
783This overrides the parent's method in order to allow the parameters to
784be provided as a hash reference.
785
786=item B<< $metaclass->constructor_class ($class_name) >>
787
788=item B<< $metaclass->destructor_class ($class_name) >>
789
790These are the names of classes used when making a class
791immutable. These default to L<Moose::Meta::Method::Constructor> and
792L<Moose::Meta::Method::Destructor> respectively. These accessors are
793read-write, so you can use them to change the class name.
794
795=item B<< $metaclass->error_class($class_name) >>
796
797The name of the class used to throw errors. This defaults to
798L<Moose::Error::Default>, which generates an error with a stacktrace
799just like C<Carp::confess>.
800
801=item B<< $metaclass->throw_error($message, %extra) >>
802
803Throws the error created by C<create_error> using C<raise_error>
804
805=back
806
807=head1 BUGS
808
809See L<Moose/BUGS> for details on reporting bugs.
810
811=head1 AUTHOR
812
813Stevan Little E<lt>stevan@iinteractive.comE<gt>
814
815=head1 COPYRIGHT AND LICENSE
816
817Copyright 2006-2010 by Infinity Interactive, Inc.
818
819L<http://www.iinteractive.com>
820
821This library is free software; you can redistribute it and/or modify
822it under the same terms as Perl itself.
823
824=cut
825
# spent 3µs within Moose::Meta::Class::CORE:match which was called 4 times, avg 675ns/call: # 4 times (3µs+0s) by Moose::Meta::Class::_process_attribute at line 596 of Moose/Meta/Class.pm, avg 675ns/call
sub Moose::Meta::Class::CORE:match; # xsub