← 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:06 2010

File /usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Class/MOP/Class.pm
Statements Executed 13349
Statement Execution Time 25.4ms
Subroutines — ordered by exclusive time
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11111.8ms49.2msClass::MOP::Class::::BEGIN@15Class::MOP::Class::BEGIN@15
9051883.79ms8.84msClass::MOP::Class::::initializeClass::MOP::Class::initialize
85642.26ms4.82msClass::MOP::Class::::get_all_attributesClass::MOP::Class::get_all_attributes
1111.63ms16.1msClass::MOP::Class::::BEGIN@8Class::MOP::Class::BEGIN@8
1111.42ms1.89msClass::MOP::Class::::BEGIN@7Class::MOP::Class::BEGIN@7
1111.35ms4.16msClass::MOP::Class::::BEGIN@9Class::MOP::Class::BEGIN@9
51111.30ms26.6msClass::MOP::Class::::_immutable_metaclassClass::MOP::Class::_immutable_metaclass
119111.22ms28.9msClass::MOP::Class::::_post_add_attributeClass::MOP::Class::_post_add_attribute
1111.18ms2.41msClass::MOP::Class::::BEGIN@10Class::MOP::Class::BEGIN@10
61111.04ms4.19msClass::MOP::Class::::_construct_class_instanceClass::MOP::Class::_construct_class_instance
6922979µs5.06msClass::MOP::Class::::find_next_method_by_nameClass::MOP::Class::find_next_method_by_name
21782979µs1.45msClass::MOP::Class::::linearized_isaClass::MOP::Class::linearized_isa
5144958µs7.64msClass::MOP::Class::::find_method_by_nameClass::MOP::Class::find_method_by_name
3211749µs33.0msClass::MOP::Class::::_inline_constructorClass::MOP::Class::_inline_constructor
5175731µs86.6msClass::MOP::Class::::make_immutableClass::MOP::Class::make_immutable
11911707µs25.2msClass::MOP::Class::::__ANON__[:515]Class::MOP::Class::__ANON__[:515]
5911657µs657µsClass::MOP::Class::::_newClass::MOP::Class::_new
11911628µs780µsClass::MOP::Class::::invalidate_meta_instancesClass::MOP::Class::invalidate_meta_instances
3611623µs7.52msClass::MOP::Class::::__ANON__[:678]Class::MOP::Class::__ANON__[:678]
5122618µs881µsClass::MOP::Class::::_immutable_optionsClass::MOP::Class::_immutable_options
5111522µs1.67msClass::MOP::Class::::find_attribute_by_nameClass::MOP::Class::find_attribute_by_name
5111514µs58.1msClass::MOP::Class::::_initialize_immutableClass::MOP::Class::_initialize_immutable
3811457µs5.52msClass::MOP::Class::::_create_meta_instanceClass::MOP::Class::_create_meta_instance
5111457µs57.6msClass::MOP::Class::::_install_inlined_codeClass::MOP::Class::_install_inlined_code
3211453µs23.4msClass::MOP::Class::::_inline_accessorsClass::MOP::Class::_inline_accessors
5111383µs27.0msClass::MOP::Class::::_rebless_as_immutableClass::MOP::Class::_rebless_as_immutable
11911374µs1.36msClass::MOP::Class::::_attach_attributeClass::MOP::Class::_attach_attribute
6721330µs416µsClass::MOP::Class::::is_anon_classClass::MOP::Class::is_anon_class
1211328µs1.24msClass::MOP::Class::::_clone_instanceClass::MOP::Class::_clone_instance
27094321µs321µsClass::MOP::Class::::instance_metaclassClass::MOP::Class::instance_metaclass
6432302µs427µsClass::MOP::Class::::_check_metaclass_compatibilityClass::MOP::Class::_check_metaclass_compatibility
621294µs3.27msClass::MOP::Class::::_construct_instanceClass::MOP::Class::_construct_instance
3611259µs8.56msClass::MOP::Class::::add_around_method_modifierClass::MOP::Class::add_around_method_modifier
722179µs467µsClass::MOP::Class::::superclassesClass::MOP::Class::superclasses
6396177µs5.69msClass::MOP::Class::::get_meta_instanceClass::MOP::Class::get_meta_instance
211155µs3.74msClass::MOP::Class::::get_all_methodsClass::MOP::Class::get_all_methods
11911152µs152µsClass::MOP::Class::::invalidate_meta_instanceClass::MOP::Class::invalidate_meta_instance
10021138µs138µsClass::MOP::Class::::immutable_traitClass::MOP::Class::immutable_trait
1211130µs1.40msClass::MOP::Class::::clone_objectClass::MOP::Class::clone_object
332191µs91µsClass::MOP::Class::::_add_inlined_methodClass::MOP::Class::_add_inlined_method
21179µs550µsClass::MOP::Class::::createClass::MOP::Class::create
511167µs67µsClass::MOP::Class::::constructor_nameClass::MOP::Class::constructor_name
501159µs59µsClass::MOP::Class::::constructor_classClass::MOP::Class::constructor_class
823354µs54µsClass::MOP::Class::::is_mutableClass::MOP::Class::is_mutable
43347µs1.90msClass::MOP::Class::::new_objectClass::MOP::Class::new_object
501147µs47µsClass::MOP::Class::::destructor_classClass::MOP::Class::destructor_class
11146µs764µsClass::MOP::Class::::_inline_destructorClass::MOP::Class::_inline_destructor
22241µs187µsClass::MOP::Class::::find_all_methods_by_nameClass::MOP::Class::find_all_methods_by_name
671231µs31µsClass::MOP::Class::::CORE:matchClass::MOP::Class::CORE:match (opcode)
31115µs23µsClass::MOP::Class::::_superclasses_updatedClass::MOP::Class::_superclasses_updated
11114µs78µsClass::MOP::Class::::BEGIN@16Class::MOP::Class::BEGIN@16
11114µs17µsClass::MOP::Class::::BEGIN@4Class::MOP::Class::BEGIN@4
11110µs3.03msClass::MOP::Class::::BEGIN@22Class::MOP::Class::BEGIN@22
11110µs21µsClass::MOP::Class::::BEGIN@223Class::MOP::Class::BEGIN@223
11210µs10µsClass::MOP::Class::::CORE:regcompClass::MOP::Class::CORE:regcomp (opcode)
1119µs44µsClass::MOP::Class::::BEGIN@12Class::MOP::Class::BEGIN@12
1119µs38µsClass::MOP::Class::::BEGIN@14Class::MOP::Class::BEGIN@14
1119µs17µsClass::MOP::Class::::BEGIN@244Class::MOP::Class::BEGIN@244
1118µs48µsClass::MOP::Class::::BEGIN@13Class::MOP::Class::BEGIN@13
1118µs20µsClass::MOP::Class::::BEGIN@5Class::MOP::Class::BEGIN@5
3118µs8µsClass::MOP::Class::::update_meta_instance_dependenciesClass::MOP::Class::update_meta_instance_dependencies
1117µs17µsClass::MOP::Class::::BEGIN@257Class::MOP::Class::BEGIN@257
6427µs7µsClass::MOP::Class::::is_immutableClass::MOP::Class::is_immutable
0000s0sClass::MOP::Class::::DESTROYClass::MOP::Class::DESTROY
0000s0sClass::MOP::Class::::__ANON__[:305]Class::MOP::Class::__ANON__[:305]
0000s0sClass::MOP::Class::::__ANON__[:519]Class::MOP::Class::__ANON__[:519]
0000s0sClass::MOP::Class::::_inlined_methodsClass::MOP::Class::_inlined_methods
0000s0sClass::MOP::Class::::_rebless_as_mutableClass::MOP::Class::_rebless_as_mutable
0000s0sClass::MOP::Class::::_remove_inlined_codeClass::MOP::Class::_remove_inlined_code
0000s0sClass::MOP::Class::::add_after_method_modifierClass::MOP::Class::add_after_method_modifier
0000s0sClass::MOP::Class::::add_before_method_modifierClass::MOP::Class::add_before_method_modifier
0000s0sClass::MOP::Class::::add_dependent_meta_instanceClass::MOP::Class::add_dependent_meta_instance
0000s0sClass::MOP::Class::::add_meta_instance_dependenciesClass::MOP::Class::add_meta_instance_dependencies
0000s0sClass::MOP::Class::::class_precedence_listClass::MOP::Class::class_precedence_list
0000s0sClass::MOP::Class::::create_anon_classClass::MOP::Class::create_anon_class
0000s0sClass::MOP::Class::::direct_subclassesClass::MOP::Class::direct_subclasses
0000s0sClass::MOP::Class::::get_all_method_namesClass::MOP::Class::get_all_method_names
0000s0sClass::MOP::Class::::immutable_optionsClass::MOP::Class::immutable_options
0000s0sClass::MOP::Class::::is_pristineClass::MOP::Class::is_pristine
0000s0sClass::MOP::Class::::make_mutableClass::MOP::Class::make_mutable
0000s0sClass::MOP::Class::::rebless_instanceClass::MOP::Class::rebless_instance
0000s0sClass::MOP::Class::::rebless_instance_awayClass::MOP::Class::rebless_instance_away
0000s0sClass::MOP::Class::::rebless_instance_backClass::MOP::Class::rebless_instance_back
0000s0sClass::MOP::Class::::remove_attributeClass::MOP::Class::remove_attribute
0000s0sClass::MOP::Class::::remove_dependent_meta_instanceClass::MOP::Class::remove_dependent_meta_instance
0000s0sClass::MOP::Class::::remove_meta_instance_dependenciesClass::MOP::Class::remove_meta_instance_dependencies
0000s0sClass::MOP::Class::::reset_package_cache_flagClass::MOP::Class::reset_package_cache_flag
0000s0sClass::MOP::Class::::subclassesClass::MOP::Class::subclasses
0000s0sClass::MOP::Class::::update_package_cache_flagClass::MOP::Class::update_package_cache_flag
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1
2package Class::MOP::Class;
3
4320µs220µs
# spent 17µs (14+3) within Class::MOP::Class::BEGIN@4 which was called # once (14µs+3µs) by Class::MOP::BEGIN@18 at line 4
use strict;
# spent 17µs making 1 call to Class::MOP::Class::BEGIN@4 # spent 3µs making 1 call to strict::import
5320µs232µs
# spent 20µs (8+12) within Class::MOP::Class::BEGIN@5 which was called # once (8µs+12µs) by Class::MOP::BEGIN@18 at line 5
use warnings;
# spent 20µs making 1 call to Class::MOP::Class::BEGIN@5 # spent 12µs making 1 call to warnings::import
6
73104µs11.89ms
# spent 1.89ms (1.42+466µs) within Class::MOP::Class::BEGIN@7 which was called # once (1.42ms+466µs) by Class::MOP::BEGIN@18 at line 7
use Class::MOP::Instance;
# spent 1.89ms making 1 call to Class::MOP::Class::BEGIN@7
83129µs116.1ms
# spent 16.1ms (1.63+14.5) within Class::MOP::Class::BEGIN@8 which was called # once (1.63ms+14.5ms) by Class::MOP::BEGIN@18 at line 8
use Class::MOP::Method::Wrapped;
# spent 16.1ms making 1 call to Class::MOP::Class::BEGIN@8
93153µs14.16ms
# spent 4.16ms (1.35+2.81) within Class::MOP::Class::BEGIN@9 which was called # once (1.35ms+2.81ms) by Class::MOP::BEGIN@18 at line 9
use Class::MOP::Method::Accessor;
# spent 4.16ms making 1 call to Class::MOP::Class::BEGIN@9
103138µs12.41ms
# spent 2.41ms (1.18+1.23) within Class::MOP::Class::BEGIN@10 which was called # once (1.18ms+1.23ms) by Class::MOP::BEGIN@18 at line 10
use Class::MOP::Method::Constructor;
# spent 2.41ms making 1 call to Class::MOP::Class::BEGIN@10
11
12332µs278µs
# spent 44µs (9+35) within Class::MOP::Class::BEGIN@12 which was called # once (9µs+35µs) by Class::MOP::BEGIN@18 at line 12
use Carp 'confess';
# spent 44µs making 1 call to Class::MOP::Class::BEGIN@12 # spent 35µs making 1 call to Exporter::import
13329µs289µs
# spent 48µs (8+40) within Class::MOP::Class::BEGIN@13 which was called # once (8µs+40µs) by Class::MOP::BEGIN@18 at line 13
use Scalar::Util 'blessed', 'reftype', 'weaken';
# spent 48µs making 1 call to Class::MOP::Class::BEGIN@13 # spent 40µs making 1 call to Exporter::import
14329µs267µs
# spent 38µs (9+29) within Class::MOP::Class::BEGIN@14 which was called # once (9µs+29µs) by Class::MOP::BEGIN@18 at line 14
use Sub::Name 'subname';
# spent 38µs making 1 call to Class::MOP::Class::BEGIN@14 # spent 29µs making 1 call to Exporter::import
153167µs249.5ms
# spent 49.2ms (11.8+37.4) within Class::MOP::Class::BEGIN@15 which was called # once (11.8ms+37.4ms) by Class::MOP::BEGIN@18 at line 15
use Devel::GlobalDestruction 'in_global_destruction';
# spent 49.2ms making 1 call to Class::MOP::Class::BEGIN@15 # spent 267µs making 1 call to Sub::Exporter::__ANON__[Sub/Exporter.pm:756]
16371µs2141µs
# spent 78µs (14+63) within Class::MOP::Class::BEGIN@16 which was called # once (14µs+63µs) by Class::MOP::BEGIN@18 at line 16
use Try::Tiny;
# spent 78µs making 1 call to Class::MOP::Class::BEGIN@16 # spent 63µs making 1 call to Exporter::import
17
181700nsour $VERSION = '0.98';
19114µs$VERSION = eval $VERSION;
201300nsour $AUTHORITY = 'cpan:STEVAN';
21
223548µs26.06ms
# spent 3.03ms (10µs+3.02) within Class::MOP::Class::BEGIN@22 which was called # once (10µs+3.02ms) by Class::MOP::BEGIN@18 at line 22
use base 'Class::MOP::Module', 'Class::MOP::Mixin::HasAttributes';
# spent 3.03ms making 1 call to Class::MOP::Class::BEGIN@22 # spent 3.02ms making 1 call to base::import
23
24# Creation
25
26
# spent 8.84ms (3.79+5.04) within Class::MOP::Class::initialize which was called 905 times, avg 10µs/call: # 293 times (1.16ms+288µs) by Class::MOP::Class::get_all_attributes at line 551, avg 5µs/call # 175 times (677µs+200µs) by Class::MOP::Class::find_method_by_name at line 729, avg 5µs/call # 133 times (598µs+842µs) by Class::MOP::Object::meta at line 17 of Class/MOP/Object.pm, avg 11µs/call # 112 times (430µs+122µs) by Class::MOP::Class::find_next_method_by_name at line 779, avg 5µs/call # 51 times (189µs+43µs) by Class::MOP::Class::find_attribute_by_name at line 541, avg 5µs/call # 43 times (205µs+102µs) by Moose::Meta::Role::Application::RoleSummation::meta or Moose::Meta::Role::Application::ToClass::meta or Moose::Meta::Role::Application::ToInstance::meta or Moose::Meta::Role::Application::ToRole::meta or Moose::Meta::Role::Application::meta or Moose::Meta::Role::Composite::meta or Moose::Meta::Role::Method::Required::meta or Moose::Meta::Role::meta or Moose::Meta::TypeCoercion::Union::meta or Moose::Meta::TypeCoercion::meta or Moose::Meta::TypeConstraint::Class::meta or Moose::Meta::TypeConstraint::DuckType::meta or Moose::Meta::TypeConstraint::Enum::meta or Moose::Meta::TypeConstraint::Parameterizable::meta or Moose::Meta::TypeConstraint::Parameterized::meta or Moose::Meta::TypeConstraint::Registry::meta or Moose::Meta::TypeConstraint::Role::meta or Moose::Meta::TypeConstraint::Union::meta or Moose::Meta::TypeConstraint::meta at line 50 of metaclass.pm, avg 7µs/call # 40 times (200µs+347µs) by Class::MOP::Mixin::meta at line 14 of Class/MOP/Mixin.pm, avg 14µs/call # 19 times (140µs+850µs) by metaclass::import at line 43 of metaclass.pm, avg 52µs/call # 12 times (40µs+11µs) by Class::MOP::Attribute::set_raw_value at line 264 of Class/MOP/Attribute.pm, avg 4µs/call # 7 times (51µs+315µs) by Moose::BEGIN@37 at line 11 of Moose/Meta/Attribute/Native.pm, avg 52µs/call # 6 times (22µs+6µs) by Class::MOP::Attribute::get_raw_value at line 272 of Class/MOP/Attribute.pm, avg 5µs/call # 3 times (13µs+3µs) by Class::MOP::Class::get_all_methods at line 740, avg 5µs/call # 2 times (16µs+1.68ms) by Moose::Meta::Class::initialize at line 62 of Moose/Meta/Class.pm, avg 850µs/call # 2 times (14µs+105µs) by Class::MOP::Class::create at line 298, avg 60µs/call # 2 times (14µs+76µs) by Class::MOP::Class::_immutable_metaclass at line 967, avg 45µs/call # 2 times (11µs+44µs) by Class::MOP::Method::_new at line 54 of Class/MOP/Method.pm, avg 27µs/call # 2 times (9µs+2µs) by Class::MOP::Attribute::has_value at line 280 of Class/MOP/Attribute.pm, avg 6µs/call # once (4µs+1µs) by Class::MOP::Attribute::_new at line 62 of Class/MOP/Attribute.pm
sub initialize {
2745253.21ms my $class = shift;
28
29 my $package_name;
30
31 if ( @_ % 2 ) {
32 $package_name = shift;
33 } else {
34 my %options = @_;
35 $package_name = $options{package};
36 }
37
38 ($package_name && !ref($package_name))
39 || confess "You must pass a package name and it cannot be blessed";
40
41 return Class::MOP::get_metaclass_by_name($package_name)
# spent 4.19ms making 61 calls to Class::MOP::Class::_construct_class_instance, avg 69µs/call # spent 979µs making 905 calls to Class::MOP::get_metaclass_by_name, avg 1µs/call
42 || $class->_construct_class_instance(package => $package_name, @_);
43}
44
45# NOTE: (meta-circularity)
46# this is a special form of _construct_instance
47# (see below), which is used to construct class
48# meta-object instances for any Class::MOP::*
49# class. All other classes will use the more
50# normal &construct_instance.
51
# spent 4.19ms (1.04+3.15) within Class::MOP::Class::_construct_class_instance which was called 61 times, avg 69µs/call: # 61 times (1.04ms+3.15ms) by Class::MOP::Class::initialize at line 41, avg 69µs/call
sub _construct_class_instance {
52734743µs my $class = shift;
53 my $options = @_ == 1 ? $_[0] : {@_};
54 my $package_name = $options->{package};
55 (defined $package_name && $package_name)
56 || confess "You must pass a package name";
57 # NOTE:
58 # return the metaclass if we have it cached,
59 # and it is still defined (it has not been
60 # reaped by DESTROY yet, which can happen
61 # annoyingly enough during global destruction)
62
63 if (defined(my $meta = Class::MOP::get_metaclass_by_name($package_name))) {
# spent 54µs making 61 calls to Class::MOP::get_metaclass_by_name, avg 879ns/call
64 return $meta;
65 }
66
67 # NOTE:
68 # we need to deal with the possibility
69 # of class immutability here, and then
70 # get the name of the class appropriately
71 $class = (ref($class)
# spent 4µs making 3 calls to Class::MOP::Class::is_immutable, avg 1µs/call
72 ? ($class->is_immutable
73 ? $class->_get_mutable_metaclass_name()
74 : ref($class))
75 : $class);
76
77 # now create the metaclass
78 my $meta;
79 if ($class eq 'Class::MOP::Class') {
# spent 657µs making 59 calls to Class::MOP::Class::_new, avg 11µs/call
80 $meta = $class->_new($options);
81 }
82 else {
83 # NOTE:
84 # it is safe to use meta here because
85 # class will always be a subclass of
86 # Class::MOP::Class, which defines meta
87 $meta = $class->meta->_construct_instance($options)
# spent 1.43ms making 2 calls to Class::MOP::Class::_construct_instance, avg 717µs/call # spent 25µs making 2 calls to Class::MOP::Object::meta, avg 13µs/call
88 }
89
90 # and check the metaclass compatibility
91 $meta->_check_metaclass_compatibility();
# spent 341µs making 59 calls to Class::MOP::Class::_check_metaclass_compatibility, avg 6µs/call # spent 153µs making 2 calls to Moose::Meta::Class::_check_metaclass_compatibility, avg 76µs/call
92
93 Class::MOP::store_metaclass_by_name($package_name, $meta);
# spent 102µs making 61 calls to Class::MOP::store_metaclass_by_name, avg 2µs/call
94
95 # NOTE:
96 # we need to weaken any anon classes
97 # so that they can call DESTROY properly
98 Class::MOP::weaken_metaclass($package_name) if $meta->is_anon_class;
# spent 380µs making 61 calls to Class::MOP::Class::is_anon_class, avg 6µs/call
99
100 $meta;
101}
102
103
# spent 657µs within Class::MOP::Class::_new which was called 59 times, avg 11µs/call: # 59 times (657µs+0s) by Class::MOP::Class::_construct_class_instance at line 79, avg 11µs/call
sub _new {
104236707µs my $class = shift;
105
106 return Class::MOP::Class->initialize($class)->new_object(@_)
107 if $class ne __PACKAGE__;
108
109 my $options = @_ == 1 ? $_[0] : {@_};
110
111 return bless {
112 # inherited from Class::MOP::Package
113 'package' => $options->{package},
114
115 # NOTE:
116 # since the following attributes will
117 # actually be loaded from the symbol
118 # table, and actually bypass the instance
119 # entirely, we can just leave these things
120 # listed here for reference, because they
121 # should not actually have a value associated
122 # with the slot.
123 'namespace' => \undef,
124 'methods' => {},
125
126 # inherited from Class::MOP::Module
127 'version' => \undef,
128 'authority' => \undef,
129
130 # defined in Class::MOP::Class
131 'superclasses' => \undef,
132
133 'attributes' => {},
134 'attribute_metaclass' =>
135 ( $options->{'attribute_metaclass'} || 'Class::MOP::Attribute' ),
136 'method_metaclass' =>
137 ( $options->{'method_metaclass'} || 'Class::MOP::Method' ),
138 'wrapped_method_metaclass' => (
139 $options->{'wrapped_method_metaclass'}
140 || 'Class::MOP::Method::Wrapped'
141 ),
142 'instance_metaclass' =>
143 ( $options->{'instance_metaclass'} || 'Class::MOP::Instance' ),
144 'immutable_trait' => (
145 $options->{'immutable_trait'}
146 || 'Class::MOP::Class::Immutable::Trait'
147 ),
148 'constructor_name' => ( $options->{constructor_name} || 'new' ),
149 'constructor_class' => (
150 $options->{constructor_class} || 'Class::MOP::Method::Constructor'
151 ),
152 'destructor_class' => $options->{destructor_class},
153 }, $class;
154}
155
156sub reset_package_cache_flag { (shift)->{'_package_cache_flag'} = undef }
157sub update_package_cache_flag {
158 my $self = shift;
159 # NOTE:
160 # we can manually update the cache number
161 # since we are actually adding the method
162 # to our cache as well. This avoids us
163 # having to regenerate the method_map.
164 # - SL
165 $self->{'_package_cache_flag'} = Class::MOP::check_package_cache_flag($self->name);
166}
167
168
# spent 427µs (302+125) within Class::MOP::Class::_check_metaclass_compatibility which was called 64 times, avg 7µs/call: # 59 times (252µs+89µs) by Class::MOP::Class::_construct_class_instance at line 91, avg 6µs/call # 3 times (42µs+34µs) by Moose::Meta::Class::_check_metaclass_compatibility at line 108 of Moose/Meta/Class.pm, avg 25µs/call # 2 times (8µs+2µs) by Class::MOP::Class::superclasses at line 579, avg 5µs/call
sub _check_metaclass_compatibility {
169141236µs my $self = shift;
170
171 # this is always okay ...
172 return if ref($self) eq 'Class::MOP::Class' &&
# spent 91µs making 61 calls to Class::MOP::Class::instance_metaclass, avg 1µs/call
173 $self->instance_metaclass eq 'Class::MOP::Instance';
174
175 my @class_list = $self->linearized_isa;
# spent 29µs making 3 calls to Class::MOP::Class::linearized_isa, avg 10µs/call
176 shift @class_list; # shift off $self->name
177
178 foreach my $superclass_name (@class_list) {
179 my $super_meta = Class::MOP::get_metaclass_by_name($superclass_name) || next;
# spent 1µs making 1 call to Class::MOP::get_metaclass_by_name
180
181 # NOTE:
182 # we need to deal with the possibility
183 # of class immutability here, and then
184 # get the name of the class appropriately
185 my $super_meta_type
# spent 700ns making 1 call to Class::MOP::Class::is_immutable
186 = $super_meta->is_immutable
187 ? $super_meta->_get_mutable_metaclass_name()
188 : ref($super_meta);
189
190 ($self->isa($super_meta_type))
# spent 600ns making 1 call to UNIVERSAL::isa
191 || confess "The metaclass of " . $self->name . " ("
192 . (ref($self)) . ")" . " is not compatible with the " .
193 "metaclass of its superclass, ".$superclass_name . " ("
194 . ($super_meta_type) . ")";
195 # NOTE:
196 # we also need to check that instance metaclasses
197 # are compatibile in the same the class.
198 ($self->instance_metaclass->isa($super_meta->instance_metaclass))
# spent 2µs making 2 calls to Class::MOP::Class::instance_metaclass, avg 1µs/call # spent 1µs making 1 call to UNIVERSAL::isa
199 || confess "The instance metaclass for " . $self->name . " (" . ($self->instance_metaclass) . ")" .
200 " is not compatible with the " .
201 "instance metaclass of its superclass, " . $superclass_name . " (" . ($super_meta->instance_metaclass) . ")";
202 }
203}
204
205## ANON classes
206
207{
208 # NOTE:
209 # this should be sufficient, if you have a
210 # use case where it is not, write a test and
211 # I will change it.
2122300ns my $ANON_CLASS_SERIAL = 0;
213
214 # NOTE:
215 # we need a sufficiently annoying prefix
216 # this should suffice for now, this is
217 # used in a couple of places below, so
218 # need to put it up here for now.
2191400ns my $ANON_CLASS_PREFIX = 'Class::MOP::Class::__ANON__::SERIAL::';
220
221
# spent 416µs (330+86) within Class::MOP::Class::is_anon_class which was called 67 times, avg 6µs/call: # 61 times (300µs+80µs) by Class::MOP::Class::_construct_class_instance at line 98, avg 6µs/call # 6 times (30µs+6µs) by Class::MOP::Class::_construct_instance at line 368, avg 6µs/call
sub is_anon_class {
222134449µs my $self = shift;
223386µs232µs
# spent 21µs (10+11) within Class::MOP::Class::BEGIN@223 which was called # once (10µs+11µs) by Class::MOP::BEGIN@18 at line 223
no warnings 'uninitialized';
# spent 21µs making 1 call to Class::MOP::Class::BEGIN@223 # spent 11µs making 1 call to warnings::unimport
224 $self->name =~ /^$ANON_CLASS_PREFIX/o;
# spent 45µs making 67 calls to Class::MOP::Package::name, avg 676ns/call # spent 31µs making 67 calls to Class::MOP::Class::CORE:match, avg 461ns/call # spent 10µs making 1 call to Class::MOP::Class::CORE:regcomp
225 }
226
227 sub create_anon_class {
228 my ($class, %options) = @_;
229 my $package_name = $ANON_CLASS_PREFIX . ++$ANON_CLASS_SERIAL;
230 return $class->create($package_name, %options);
231 }
232
233 # NOTE:
234 # this will only get called for
235 # anon-classes, all other calls
236 # are assumed to occur during
237 # global destruction and so don't
238 # really need to be handled explicitly
239 sub DESTROY {
240 my $self = shift;
241
242 return if in_global_destruction(); # it'll happen soon anyway and this just makes things more complicated
243
244369µs226µs
# spent 17µs (9+9) within Class::MOP::Class::BEGIN@244 which was called # once (9µs+9µs) by Class::MOP::BEGIN@18 at line 244
no warnings 'uninitialized';
# spent 17µs making 1 call to Class::MOP::Class::BEGIN@244 # spent 9µs making 1 call to warnings::unimport
245 my $name = $self->name;
246 return unless $name =~ /^$ANON_CLASS_PREFIX/o;
247
248 # Moose does a weird thing where it replaces the metaclass for
249 # class when fixing metaclass incompatibility. In that case,
250 # we don't want to clean out the namespace now. We can detect
251 # that because Moose will explicitly update the singleton
252 # cache in Class::MOP.
253 my $current_meta = Class::MOP::get_metaclass_by_name($name);
254 return if $current_meta ne $self;
255
256 my ($serial_id) = ($name =~ /^$ANON_CLASS_PREFIX(\d+)/o);
25732.81ms227µs
# spent 17µs (7+10) within Class::MOP::Class::BEGIN@257 which was called # once (7µs+10µs) by Class::MOP::BEGIN@18 at line 257
no strict 'refs';
# spent 17µs making 1 call to Class::MOP::Class::BEGIN@257 # spent 10µs making 1 call to strict::unimport
258 @{$name . '::ISA'} = ();
259 %{$name . '::'} = ();
260 delete ${$ANON_CLASS_PREFIX}{$serial_id . '::'};
261
262 Class::MOP::remove_metaclass_by_name($name);
263 }
264
265}
266
267# creating classes with MOP ...
268
269
# spent 550µs (79+471) within Class::MOP::Class::create which was called 2 times, avg 275µs/call: # 2 times (79µs+471µs) by Class::MOP::Class::_immutable_metaclass at line 961, avg 275µs/call
sub create {
2703267µs my ( $class, @args ) = @_;
271
272 unshift @args, 'package' if @args % 2 == 1;
273
274 my (%options) = @args;
275 my $package_name = $options{package};
276
277 (ref $options{superclasses} eq 'ARRAY')
278 || confess "You must pass an ARRAY ref of superclasses"
279 if exists $options{superclasses};
280
281 (ref $options{attributes} eq 'ARRAY')
282 || confess "You must pass an ARRAY ref of attributes"
283 if exists $options{attributes};
284
285 (ref $options{methods} eq 'HASH')
286 || confess "You must pass a HASH ref of methods"
287 if exists $options{methods};
288
289 my (%initialize_options) = @args;
290 delete @initialize_options{qw(
291 package
292 superclasses
293 attributes
294 methods
295 version
296 authority
297 )};
298 my $meta = $class->initialize( $package_name => %initialize_options );
# spent 119µs making 2 calls to Class::MOP::Class::initialize, avg 60µs/call
299
300 $meta->_instantiate_module( $options{version}, $options{authority} );
# spent 74µs making 2 calls to Class::MOP::Module::_instantiate_module, avg 37µs/call
301
302 # FIXME totally lame
303 $meta->add_method('meta' => sub {
304 $class->initialize(ref($_[0]) || $_[0]);
305 });
# spent 78µs making 2 calls to Class::MOP::Mixin::HasMethods::add_method, avg 39µs/call
306
307 $meta->superclasses(@{$options{superclasses}})
# spent 201µs making 2 calls to Class::MOP::Class::superclasses, avg 100µs/call
308 if exists $options{superclasses};
309 # NOTE:
310 # process attributes first, so that they can
311 # install accessors, but locally defined methods
312 # can then overwrite them. It is maybe a little odd, but
313 # I think this should be the order of things.
314 if (exists $options{attributes}) {
315 foreach my $attr (@{$options{attributes}}) {
316 $meta->add_attribute($attr);
317 }
318 }
319 if (exists $options{methods}) {
320 foreach my $method_name (keys %{$options{methods}}) {
321 $meta->add_method($method_name, $options{methods}->{$method_name});
322 }
323 }
324 return $meta;
325}
326
327## Attribute readers
328
329# NOTE:
330# all these attribute readers will be bootstrapped
331# away in the Class::MOP bootstrap section
332
333270566µs
# spent 321µs within Class::MOP::Class::instance_metaclass which was called 270 times, avg 1µs/call: # 84 times (94µs+0s) by Class::MOP::Attribute::_process_accessors at line 320 of Class/MOP/Attribute.pm, avg 1µs/call # 61 times (91µs+0s) by Class::MOP::Class::_check_metaclass_compatibility at line 172, avg 1µs/call # 52 times (58µs+0s) by Class::MOP::Method::Accessor::_generate_reader_method_inline at line 155 of Class/MOP/Method/Accessor.pm, avg 1µs/call # 38 times (43µs+0s) by Class::MOP::Class::_create_meta_instance at line 390, avg 1µs/call # 15 times (15µs+0s) by Class::MOP::Method::Accessor::_generate_accessor_method_inline at line 136 of Class/MOP/Method/Accessor.pm, avg 987ns/call # 13 times (13µs+0s) by Class::MOP::Method::Accessor::_generate_predicate_method_inline at line 190 of Class/MOP/Method/Accessor.pm, avg 1µs/call # 3 times (3µs+0s) by Class::MOP::Method::Accessor::_generate_writer_method_inline at line 173 of Class/MOP/Method/Accessor.pm, avg 1µs/call # 2 times (3µs+0s) by Moose::Meta::Class::_superclass_meta_is_compatible at line 378 of Moose/Meta/Class.pm, avg 1µs/call # 2 times (2µs+0s) by Class::MOP::Class::_check_metaclass_compatibility at line 198, avg 1µs/call
sub instance_metaclass { $_[0]->{'instance_metaclass'} }
334100224µs
# spent 138µs within Class::MOP::Class::immutable_trait which was called 100 times, avg 1µs/call: # 50 times (80µs+0s) by Class::MOP::Class::_immutable_options at line 876, avg 2µs/call # 50 times (58µs+0s) by Class::MOP::Class::_immutable_metaclass at line 931, avg 1µs/call
sub immutable_trait { $_[0]->{'immutable_trait'} }
3355095µs
# spent 59µs within Class::MOP::Class::constructor_class which was called 50 times, avg 1µs/call: # 50 times (59µs+0s) by Class::MOP::Class::_immutable_options at line 876, avg 1µs/call
sub constructor_class { $_[0]->{'constructor_class'} }
3365198µs
# spent 67µs within Class::MOP::Class::constructor_name which was called 51 times, avg 1µs/call: # 51 times (67µs+0s) by Class::MOP::Class::_immutable_options at line 876, avg 1µs/call
sub constructor_name { $_[0]->{'constructor_name'} }
3375079µs
# spent 47µs within Class::MOP::Class::destructor_class which was called 50 times, avg 936ns/call: # 50 times (47µs+0s) by Class::MOP::Class::_immutable_options at line 876, avg 936ns/call
sub destructor_class { $_[0]->{'destructor_class'} }
338
339# Instance Construction & Cloning
340
341
# spent 1.90ms (47µs+1.85) within Class::MOP::Class::new_object which was called 4 times, avg 475µs/call: # 2 times (20µs+951µs) by Class::MOP::Method::_new at line 54 of Class/MOP/Method.pm, avg 486µs/call # once (14µs+618µs) by Class::MOP::Attribute::_new at line 62 of Class/MOP/Attribute.pm # once (13µs+284µs) by Class::MOP::Object::_new at line 21 of Class/MOP/Object.pm
sub new_object {
3421259µs my $class = shift;
343
344 # NOTE:
345 # we need to protect the integrity of the
346 # Class::MOP::Class singletons here, so we
347 # delegate this to &construct_class_instance
348 # which will deal with the singletons
349 return $class->_construct_class_instance(@_)
# spent 8µs making 4 calls to UNIVERSAL::isa, avg 2µs/call # spent 3µs making 4 calls to Class::MOP::Package::name, avg 675ns/call
350 if $class->name->isa('Class::MOP::Class');
351 return $class->_construct_instance(@_);
# spent 1.84ms making 4 calls to Class::MOP::Class::_construct_instance, avg 460µs/call
352}
353
354
# spent 3.27ms (294µs+2.98) within Class::MOP::Class::_construct_instance which was called 6 times, avg 546µs/call: # 4 times (175µs+1.67ms) by Class::MOP::Class::new_object at line 351, avg 460µs/call # 2 times (119µs+1.31ms) by Class::MOP::Class::_construct_class_instance at line 87, avg 717µs/call
sub _construct_instance {
355126179µs my $class = shift;
356 my $params = @_ == 1 ? $_[0] : {@_};
357 my $meta_instance = $class->get_meta_instance();
# spent 875µs making 5 calls to Class::MOP::Class::get_meta_instance, avg 175µs/call # spent 18µs making 1 call to Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance
358 # FIXME:
359 # the code below is almost certainly incorrect
360 # but this is foreign inheritance, so we might
361 # have to kludge it in the end.
362 my $instance = $params->{__INSTANCE__} || $meta_instance->create_instance();
# spent 399µs making 6 calls to Class::MOP::Instance::create_instance, avg 67µs/call
363 foreach my $attr ($class->get_all_attributes()) {
# spent 347µs making 5 calls to Class::MOP::Class::get_all_attributes, avg 69µs/call # spent 144µs making 1 call to Class::MOP::Class::Immutable::Class::MOP::Class::get_all_attributes
364 $attr->initialize_instance_slot($meta_instance, $instance, $params);
# spent 1.16ms making 84 calls to Class::MOP::Attribute::initialize_instance_slot, avg 14µs/call
365 }
366 # NOTE:
367 # this will only work for a HASH instance type
368 if ($class->is_anon_class) {
# spent 36µs making 6 calls to Class::MOP::Class::is_anon_class, avg 6µs/call
369 (reftype($instance) eq 'HASH')
370 || confess "Currently only HASH based instances are supported with instance of anon-classes";
371 # NOTE:
372 # At some point we should make this official
373 # as a reserved slot name, but right now I am
374 # going to keep it here.
375 # my $RESERVED_MOP_SLOT = '__MOP__';
376 $instance->{'__MOP__'} = $class;
377 }
378 return $instance;
379}
380
381
382
# spent 5.69ms (177µs+5.52) within Class::MOP::Class::get_meta_instance which was called 63 times, avg 90µs/call: # 32 times (101µs+3.74ms) by Class::MOP::Method::Constructor::_meta_instance at line 77 of Class/MOP/Method/Constructor.pm, avg 120µs/call # 6 times (24µs+605µs) by Moose::Meta::Method::Accessor::_inline_get at line 252 of Moose/Meta/Method/Accessor.pm, avg 105µs/call # 6 times (10µs+105µs) by Class::MOP::Class::_clone_instance at line 419, avg 19µs/call # 6 times (7µs+0s) by Class::MOP::Attribute::set_raw_value at line 264 of Class/MOP/Attribute.pm, avg 1µs/call # 5 times (19µs+856µs) by Class::MOP::Class::_construct_instance at line 357, avg 175µs/call # 3 times (4µs+0s) by Class::MOP::Class:::around at line 74 of Class/MOP/Class/Immutable/Trait.pm, avg 1µs/call # 3 times (4µs+0s) by Class::MOP::Attribute::get_raw_value at line 272 of Class/MOP/Attribute.pm, avg 1µs/call # once (6µs+208µs) by Moose::Exporter::BEGIN@11 at line 663 of Class/MOP.pm # once (2µs+0s) by Class::MOP::Attribute::has_value at line 280 of Class/MOP/Attribute.pm
sub get_meta_instance {
383126191µs my $self = shift;
384 $self->{'_meta_instance'} ||= $self->_create_meta_instance();
# spent 5.52ms making 38 calls to Class::MOP::Class::_create_meta_instance, avg 145µs/call
385}
386
387
# spent 5.52ms (457µs+5.06) within Class::MOP::Class::_create_meta_instance which was called 38 times, avg 145µs/call: # 38 times (457µs+5.06ms) by Class::MOP::Class::get_meta_instance at line 384, avg 145µs/call
sub _create_meta_instance {
388152313µs my $self = shift;
389
390 my $instance = $self->instance_metaclass->new(
# spent 2.85ms making 38 calls to Class::MOP::Instance::new, avg 75µs/call # spent 2.13ms making 38 calls to Class::MOP::Class::get_all_attributes, avg 56µs/call # spent 43µs making 38 calls to Class::MOP::Class::instance_metaclass, avg 1µs/call
391 associated_metaclass => $self,
392 attributes => [ $self->get_all_attributes() ],
393 );
394
395 $self->add_meta_instance_dependencies()
# spent 36µs making 38 calls to Class::MOP::Instance::is_dependent_on_superclasses, avg 937ns/call
396 if $instance->is_dependent_on_superclasses();
397
398 return $instance;
399}
400
401
# spent 1.40ms (130µs+1.27) within Class::MOP::Class::clone_object which was called 12 times, avg 117µs/call: # 12 times (130µs+1.27ms) by Class::MOP::Method::clone at line 538 of Class/MOP.pm, avg 117µs/call
sub clone_object {
40260153µs my $class = shift;
403 my $instance = shift;
404 (blessed($instance) && $instance->isa($class->name))
# spent 8µs making 12 calls to UNIVERSAL::isa, avg 692ns/call # spent 6µs making 12 calls to Class::MOP::Package::name, avg 500ns/call # spent 6µs making 12 calls to Scalar::Util::blessed, avg 475ns/call
405 || confess "You must pass an instance of the metaclass (" . (ref $class ? $class->name : $class) . "), not ($instance)";
406
407 # NOTE:
408 # we need to protect the integrity of the
409 # Class::MOP::Class singletons here, they
410 # should not be cloned.
411 return $instance if $instance->isa('Class::MOP::Class');
# spent 11µs making 12 calls to UNIVERSAL::isa, avg 942ns/call
412 $class->_clone_instance($instance, @_);
# spent 1.24ms making 12 calls to Class::MOP::Class::_clone_instance, avg 103µs/call
413}
414
415
# spent 1.24ms (328µs+909µs) within Class::MOP::Class::_clone_instance which was called 12 times, avg 103µs/call: # 12 times (328µs+909µs) by Class::MOP::Class::clone_object at line 412, avg 103µs/call
sub _clone_instance {
416132227µs my ($class, $instance, %params) = @_;
417 (blessed($instance))
# spent 5µs making 12 calls to Scalar::Util::blessed, avg 425ns/call
418 || confess "You can only clone instances, ($instance) is not a blessed instance";
419 my $meta_instance = $class->get_meta_instance();
# spent 115µs making 6 calls to Class::MOP::Class::get_meta_instance, avg 19µs/call # spent 52µs making 6 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance, avg 9µs/call
420 my $clone = $meta_instance->clone_instance($instance);
# spent 116µs making 12 calls to Class::MOP::Instance::clone_instance, avg 10µs/call
421 foreach my $attr ($class->get_all_attributes()) {
# spent 188µs making 6 calls to Class::MOP::Class::get_all_attributes, avg 31µs/call # spent 92µs making 6 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_all_attributes, avg 15µs/call
422 if ( defined( my $init_arg = $attr->init_arg ) ) {
# spent 271µs making 12 calls to Class::MOP::Attribute::set_value, avg 23µs/call # spent 71µs making 60 calls to Class::MOP::Mixin::AttributeCore::init_arg, avg 1µs/call
423 if (exists $params{$init_arg}) {
424 $attr->set_value($clone, $params{$init_arg});
425 }
426 }
427 }
428 return $clone;
429}
430
431sub rebless_instance {
432 my ($self, $instance, %params) = @_;
433
434 my $old_metaclass = Class::MOP::class_of($instance);
435
436 my $old_class = $old_metaclass ? $old_metaclass->name : blessed($instance);
437 $self->name->isa($old_class)
438 || confess "You may rebless only into a subclass of ($old_class), of which (". $self->name .") isn't.";
439
440 $old_metaclass->rebless_instance_away($instance, $self, %params)
441 if $old_metaclass;
442
443 my $meta_instance = $self->get_meta_instance();
444
445 # rebless!
446 # we use $_[1] here because of t/306_rebless_overload.t regressions on 5.8.8
447 $meta_instance->rebless_instance_structure($_[1], $self);
448
449 foreach my $attr ( $self->get_all_attributes ) {
450 if ( $attr->has_value($instance) ) {
451 if ( defined( my $init_arg = $attr->init_arg ) ) {
452 $params{$init_arg} = $attr->get_value($instance)
453 unless exists $params{$init_arg};
454 }
455 else {
456 $attr->set_value($instance, $attr->get_value($instance));
457 }
458 }
459 }
460
461 foreach my $attr ($self->get_all_attributes) {
462 $attr->initialize_instance_slot($meta_instance, $instance, \%params);
463 }
464
465 $instance;
466}
467
468sub rebless_instance_back {
469 my ( $self, $instance ) = @_;
470
471 my $old_metaclass = Class::MOP::class_of($instance);
472
473 my $old_class
474 = $old_metaclass ? $old_metaclass->name : blessed($instance);
475 $old_class->isa( $self->name )
476 || confess
477 "You may rebless only into a superclass of ($old_class), of which ("
478 . $self->name
479 . ") isn't.";
480
481 $old_metaclass->rebless_instance_away( $instance, $self )
482 if $old_metaclass;
483
484 my $meta_instance = $self->get_meta_instance;
485
486 # we use $_[1] here because of t/306_rebless_overload.t regressions on 5.8.8
487 $meta_instance->rebless_instance_structure( $_[1], $self );
488
489 for my $attr ( $old_metaclass->get_all_attributes ) {
490 next if $self->has_attribute( $attr->name );
491 $meta_instance->deinitialize_slot( $instance, $_ ) for $attr->slots;
492 }
493
494 return $instance;
495}
496
497sub rebless_instance_away {
498 # this intentionally does nothing, it is just a hook
499}
500
501
# spent 1.36ms (374µs+982µs) within Class::MOP::Class::_attach_attribute which was called 119 times, avg 11µs/call: # 119 times (374µs+982µs) by Class::MOP::Mixin::HasAttributes::add_attribute at line 28 of Class/MOP/Mixin/HasAttributes.pm, avg 11µs/call
sub _attach_attribute {
502238326µs my ($self, $attribute) = @_;
503 $attribute->attach_to_class($self);
# spent 982µs making 119 calls to Class::MOP::Attribute::attach_to_class, avg 8µs/call
504}
505
506
# spent 28.9ms (1.22+27.7) within Class::MOP::Class::_post_add_attribute which was called 119 times, avg 243µs/call: # 119 times (1.22ms+27.7ms) by Class::MOP::Mixin::HasAttributes::add_attribute at line 45 of Class/MOP/Mixin/HasAttributes.pm, avg 243µs/call
sub _post_add_attribute {
507357981µs my ( $self, $attribute ) = @_;
508
509 $self->invalidate_meta_instances;
# spent 780µs making 119 calls to Class::MOP::Class::invalidate_meta_instances, avg 7µs/call
510
511 # invalidate package flag here
512
# spent 25.2ms (707µs+24.5) within Class::MOP::Class::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Class/MOP/Class.pm:515] which was called 119 times, avg 212µs/call: # 119 times (707µs+24.5ms) by Try::Tiny::try at line 76 of Try/Tiny.pm, avg 212µs/call
try {
513238644µs local $SIG{__DIE__};
514 $attribute->install_accessors;
# spent 20.1ms making 114 calls to Class::MOP::Attribute::install_accessors, avg 176µs/call # spent 4.44ms making 5 calls to Moose::Meta::Attribute::install_accessors, avg 888µs/call
515 }
516 catch {
517 $self->remove_attribute( $attribute->name );
518 die $_;
519 };
# spent 26.5ms making 119 calls to Try::Tiny::try, avg 223µs/call # spent 367µs making 119 calls to Try::Tiny::catch, avg 3µs/call
520}
521
522sub remove_attribute {
523 my $self = shift;
524
525 my $removed_attribute = $self->SUPER::remove_attribute(@_)
526 or return;
527
528 $self->invalidate_meta_instances;
529
530 $removed_attribute->remove_accessors;
531 $removed_attribute->detach_from_class;
532
533 return$removed_attribute;
534}
535
536
# spent 1.67ms (522µs+1.15) within Class::MOP::Class::find_attribute_by_name which was called 51 times, avg 33µs/call: # 51 times (522µs+1.15ms) by Class::MOP::Class::_immutable_metaclass at line 935, avg 33µs/call
sub find_attribute_by_name {
537204361µs my ( $self, $attr_name ) = @_;
538
539 foreach my $class ( $self->linearized_isa ) {
# spent 419µs making 47 calls to Class::MOP::Class::Immutable::Class::MOP::Class::linearized_isa, avg 9µs/call # spent 23µs making 4 calls to Class::MOP::Class::linearized_isa, avg 6µs/call
540 # fetch the meta-class ...
541 my $meta = $self->initialize($class);
# spent 232µs making 51 calls to Class::MOP::Class::initialize, avg 5µs/call
542 return $meta->get_attribute($attr_name)
# spent 265µs making 51 calls to Class::MOP::Mixin::HasAttributes::has_attribute, avg 5µs/call # spent 213µs making 51 calls to Class::MOP::Mixin::HasAttributes::get_attribute, avg 4µs/call
543 if $meta->has_attribute($attr_name);
544 }
545
546 return;
547}
548
549
# spent 4.82ms (2.26+2.57) within Class::MOP::Class::get_all_attributes which was called 85 times, avg 57µs/call: # 38 times (970µs+1.16ms) by Class::MOP::Class::_create_meta_instance at line 390, avg 56µs/call # 32 times (811µs+896µs) by Class::MOP::Method::Constructor::_attributes at line 82 of Class/MOP/Method/Constructor.pm, avg 53µs/call # 6 times (91µs+96µs) by Class::MOP::Class::_clone_instance at line 421, avg 31µs/call # 5 times (171µs+176µs) by Class::MOP::Class::_construct_instance at line 363, avg 69µs/call # 3 times (162µs+195µs) by Class::MOP::Class:::around at line 68 of Class/MOP/Class/Immutable/Trait.pm, avg 119µs/call # once (51µs+42µs) by Moose::Meta::Attribute::new at line 59 of Moose/Meta/Attribute.pm
sub get_all_attributes {
5508611.60ms my $self = shift;
551 my %attrs = map { %{ $self->initialize($_)->_attribute_map } }
# spent 1.56ms making 293 calls to Class::MOP::Class::initialize, avg 5µs/call, recursion: max depth 1, time 112µs # spent 554µs making 82 calls to Class::MOP::Class::linearized_isa, avg 7µs/call # spent 330µs making 303 calls to Class::MOP::Mixin::HasAttributes::_attribute_map, avg 1µs/call # spent 75µs making 3 calls to Class::MOP::Class::Immutable::Class::MOP::Class::linearized_isa, avg 25µs/call # spent 49µs making 10 calls to Moose::Meta::Class::initialize, avg 5µs/call
552 reverse $self->linearized_isa;
553 return values %attrs;
554}
555
556# Inheritance
557
558
# spent 467µs (179+288) within Class::MOP::Class::superclasses which was called 7 times, avg 67µs/call: # 5 times (65µs+202µs) by Moose::Meta::Class::superclasses at line 289 of Moose/Meta/Class.pm, avg 53µs/call # 2 times (114µs+87µs) by Class::MOP::Class::create at line 307, avg 100µs/call
sub superclasses {
55946169µs my $self = shift;
560 my $var_spec = { sigil => '@', type => 'ARRAY', name => 'ISA' };
561 if (@_) {
562 my @supers = @_;
563 @{$self->get_package_symbol($var_spec)} = @supers;
# spent 50µs making 3 calls to Class::MOP::Package::get_package_symbol, avg 17µs/call
564
565 # NOTE:
566 # on 5.8 and below, we need to call
567 # a method to get Perl to detect
568 # a cycle in the class hierarchy
569 my $class = $self->name;
# spent 2µs making 3 calls to Class::MOP::Package::name, avg 767ns/call
570 $class->isa($class);
# spent 4µs making 3 calls to UNIVERSAL::isa, avg 1µs/call
571
572 # NOTE:
573 # we need to check the metaclass
574 # compatibility here so that we can
575 # be sure that the superclass is
576 # not potentially creating an issues
577 # we don't know about
578
579 $self->_check_metaclass_compatibility();
# spent 134µs making 1 call to Moose::Meta::Class::_check_metaclass_compatibility # spent 11µs making 2 calls to Class::MOP::Class::_check_metaclass_compatibility, avg 5µs/call
580 $self->_superclasses_updated();
# spent 23µs making 3 calls to Class::MOP::Class::_superclasses_updated, avg 8µs/call
581 }
582 @{$self->get_package_symbol($var_spec)};
# spent 78µs making 7 calls to Class::MOP::Package::get_package_symbol, avg 11µs/call
583}
584
585
# spent 23µs (15+8) within Class::MOP::Class::_superclasses_updated which was called 3 times, avg 8µs/call: # 3 times (15µs+8µs) by Class::MOP::Class::superclasses at line 580, avg 8µs/call
sub _superclasses_updated {
586614µs my $self = shift;
587 $self->update_meta_instance_dependencies();
# spent 8µs making 3 calls to Class::MOP::Class::update_meta_instance_dependencies, avg 3µs/call
588}
589
590sub subclasses {
591 my $self = shift;
592 my $super_class = $self->name;
593
594 return @{ $super_class->mro::get_isarev() };
595}
596
597sub direct_subclasses {
598 my $self = shift;
599 my $super_class = $self->name;
600
601 return grep {
602 grep {
603 $_ eq $super_class
604 } Class::MOP::Class->initialize($_)->superclasses
605 } $self->subclasses;
606}
607
608
# spent 1.45ms (979µs+473µs) within Class::MOP::Class::linearized_isa which was called 217 times, avg 7µs/call: # 82 times (375µs+179µs) by Class::MOP::Class::get_all_attributes at line 551, avg 7µs/call # 69 times (296µs+142µs) by Class::MOP::Class::find_next_method_by_name at line 776, avg 6µs/call # 51 times (228µs+113µs) by Class::MOP::Class::find_method_by_name at line 728, avg 7µs/call # 4 times (32µs+10µs) by Class::MOP::Class:::around at line 50 of Class/MOP/Class/Immutable/Trait.pm, avg 10µs/call # 4 times (16µs+7µs) by Class::MOP::Class::find_attribute_by_name at line 539, avg 6µs/call # 3 times (15µs+14µs) by Class::MOP::Class::_check_metaclass_compatibility at line 175, avg 10µs/call # 2 times (9µs+5µs) by Class::MOP::Class::get_all_methods at line 739, avg 7µs/call # 2 times (8µs+3µs) by Class::MOP::Class::find_all_methods_by_name at line 760, avg 6µs/call
sub linearized_isa {
6092171.64ms434473µs return @{ mro::get_linear_isa( (shift)->name ) };
# spent 366µs making 217 calls to mro::get_linear_isa, avg 2µs/call # spent 108µs making 217 calls to Class::MOP::Package::name, avg 496ns/call
610}
611
612sub class_precedence_list {
613 my $self = shift;
614 my $name = $self->name;
615
616 unless (Class::MOP::IS_RUNNING_ON_5_10()) {
617 # NOTE:
618 # We need to check for circular inheritance here
619 # if we are are not on 5.10, cause 5.8 detects it
620 # late. This will do nothing if all is well, and
621 # blow up otherwise. Yes, it's an ugly hack, better
622 # suggestions are welcome.
623 # - SL
624 ($name || return)->isa('This is a test for circular inheritance')
625 }
626
627 # if our mro is c3, we can
628 # just grab the linear_isa
629 if (mro::get_mro($name) eq 'c3') {
630 return @{ mro::get_linear_isa($name) }
631 }
632 else {
633 # NOTE:
634 # we can't grab the linear_isa for dfs
635 # since it has all the duplicates
636 # already removed.
637 return (
638 $name,
639 map {
640 $self->initialize($_)->class_precedence_list()
641 } $self->superclasses()
642 );
643 }
644}
645
646## Methods
647
648{
6491200ns
# spent 7.52ms (623µs+6.90) within Class::MOP::Class::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Class/MOP/Class.pm:678] which was called 36 times, avg 209µs/call: # 36 times (623µs+6.90ms) by Class::MOP::Class::add_around_method_modifier at line 704, avg 209µs/call
my $fetch_and_prepare_method = sub {
650324456µs my ($self, $method_name) = @_;
651 my $wrapped_metaclass = $self->wrapped_method_metaclass;
# spent 47µs making 36 calls to Class::MOP::Mixin::HasMethods::wrapped_method_metaclass, avg 1µs/call
652 # fetch it locally
653 my $method = $self->get_method($method_name);
# spent 704µs making 36 calls to Class::MOP::Mixin::HasMethods::get_method, avg 20µs/call
654 # if we dont have local ...
655 unless ($method) {
656 # try to find the next method
657 $method = $self->find_next_method_by_name($method_name);
# spent 2.77ms making 36 calls to Class::MOP::Class::find_next_method_by_name, avg 77µs/call
658 # die if it does not exist
659 (defined $method)
660 || confess "The method '$method_name' was not found in the inheritance hierarchy for " . $self->name;
661 # and now make sure to wrap it
662 # even if it is already wrapped
663 # because we need a new sub ref
664 $method = $wrapped_metaclass->wrap($method,
# spent 1.82ms making 36 calls to Class::MOP::Method::Wrapped::wrap, avg 50µs/call # spent 20µs making 36 calls to Class::MOP::Package::name, avg 544ns/call
665 package_name => $self->name,
666 name => $method_name,
667 );
668 }
669 else {
670 # now make sure we wrap it properly
671 $method = $wrapped_metaclass->wrap($method,
672 package_name => $self->name,
673 name => $method_name,
674 ) unless $method->isa($wrapped_metaclass);
675 }
676 $self->add_method($method_name => $method);
# spent 1.54ms making 36 calls to Class::MOP::Mixin::HasMethods::add_method, avg 43µs/call
677 return $method;
67812µs };
679
680 sub add_before_method_modifier {
681 my ($self, $method_name, $method_modifier) = @_;
682 (defined $method_name && length $method_name)
683 || confess "You must pass in a method name";
684 my $method = $fetch_and_prepare_method->($self, $method_name);
685 $method->add_before_modifier(
686 subname(':before' => $method_modifier)
687 );
688 }
689
690 sub add_after_method_modifier {
691 my ($self, $method_name, $method_modifier) = @_;
692 (defined $method_name && length $method_name)
693 || confess "You must pass in a method name";
694 my $method = $fetch_and_prepare_method->($self, $method_name);
695 $method->add_after_modifier(
696 subname(':after' => $method_modifier)
697 );
698 }
699
700
# spent 8.56ms (259µs+8.30) within Class::MOP::Class::add_around_method_modifier which was called 36 times, avg 238µs/call: # 36 times (259µs+8.30ms) by Class::MOP::Class::_immutable_metaclass at line 970, avg 238µs/call
sub add_around_method_modifier {
701144289µs my ($self, $method_name, $method_modifier) = @_;
702 (defined $method_name && length $method_name)
703 || confess "You must pass in a method name";
704 my $method = $fetch_and_prepare_method->($self, $method_name);
# spent 7.52ms making 36 calls to Class::MOP::Class::__ANON__[Class/MOP/Class.pm:678], avg 209µs/call
705 $method->add_around_modifier(
# spent 697µs making 36 calls to Class::MOP::Method::Wrapped::add_around_modifier, avg 19µs/call # spent 79µs making 36 calls to Sub::Name::subname, avg 2µs/call
706 subname(':around' => $method_modifier)
707 );
708 }
709
710 # NOTE:
711 # the methods above used to be named like this:
712 # ${pkg}::${method}:(before|after|around)
713 # but this proved problematic when using one modifier
714 # to wrap multiple methods (something which is likely
715 # to happen pretty regularly IMO). So instead of naming
716 # it like this, I have chosen to just name them purely
717 # with their modifier names, like so:
718 # :(before|after|around)
719 # The fact is that in a stack trace, it will be fairly
720 # evident from the context what method they are attached
721 # to, and so don't need the fully qualified name.
722}
723
724
# spent 7.64ms (958µs+6.69) within Class::MOP::Class::find_method_by_name which was called 51 times, avg 150µs/call: # 42 times (844µs+6.00ms) by Class::MOP::Class::_immutable_metaclass at line 970, avg 163µs/call # 7 times (83µs+360µs) by Moose::BEGIN@37 at line 14 of Moose/Meta/Attribute/Native.pm, avg 63µs/call # once (18µs+221µs) by Moose::Meta::Method::Constructor::_generate_BUILDARGS at line 135 of Moose/Meta/Method/Constructor.pm # once (13µs+105µs) by Moose::Meta::Method::Destructor::is_needed at line 62 of Moose/Meta/Method/Destructor.pm
sub find_method_by_name {
725524602µs my ($self, $method_name) = @_;
726 (defined $method_name && length $method_name)
727 || confess "You must define a method name to find";
728 foreach my $class ($self->linearized_isa) {
# spent 341µs making 51 calls to Class::MOP::Class::linearized_isa, avg 7µs/call
729 my $method = $self->initialize($class)->get_method($method_name);
# spent 5.45ms making 179 calls to Class::MOP::Mixin::HasMethods::get_method, avg 30µs/call # spent 876µs making 175 calls to Class::MOP::Class::initialize, avg 5µs/call # spent 17µs making 4 calls to Moose::Meta::Class::initialize, avg 4µs/call
730 return $method if defined $method;
731 }
732 return;
733}
734
735
# spent 3.74ms (155µs+3.58) within Class::MOP::Class::get_all_methods which was called 2 times, avg 1.87ms/call: # 2 times (155µs+3.58ms) by Class::MOP::Class::_immutable_metaclass at line 967, avg 1.87ms/call
sub get_all_methods {
73617109µs my $self = shift;
737
738 my %methods;
739 for my $class ( reverse $self->linearized_isa ) {
# spent 14µs making 2 calls to Class::MOP::Class::linearized_isa, avg 7µs/call
740 my $meta = $self->initialize($class);
# spent 16µs making 3 calls to Class::MOP::Class::initialize, avg 5µs/call
741
742 $methods{$_} = $meta->get_method($_)
743 for $meta->get_method_list;
# spent 2.71ms making 3 calls to Class::MOP::Mixin::HasMethods::get_method_list, avg 904µs/call # spent 843µs making 42 calls to Class::MOP::Mixin::HasMethods::get_method, avg 20µs/call
744 }
745
746 return values %methods;
747}
748
749sub get_all_method_names {
750 my $self = shift;
751 my %uniq;
752 return grep { !$uniq{$_}++ } map { $self->initialize($_)->get_method_list } $self->linearized_isa;
753}
754
755
# spent 187µs (41+146) within Class::MOP::Class::find_all_methods_by_name which was called 2 times, avg 93µs/call: # once (28µs+74µs) by Moose::Meta::Method::Constructor::_generate_BUILDALL at line 153 of Moose/Meta/Method/Constructor.pm # once (14µs+71µs) by Moose::Meta::Method::Destructor::_initialize_body at line 81 of Moose/Meta/Method/Destructor.pm
sub find_all_methods_by_name {
7561824µs my ($self, $method_name) = @_;
757 (defined $method_name && length $method_name)
758 || confess "You must define a method name to find";
759 my @methods;
760 foreach my $class ($self->linearized_isa) {
# spent 12µs making 2 calls to Class::MOP::Class::linearized_isa, avg 6µs/call
761 # fetch the meta-class ...
762 my $meta = $self->initialize($class);
# spent 17µs making 4 calls to Moose::Meta::Class::initialize, avg 4µs/call
763 push @methods => {
# spent 117µs making 4 calls to Class::MOP::Mixin::HasMethods::has_method, avg 29µs/call
764 name => $method_name,
765 class => $class,
766 code => $meta->get_method($method_name)
767 } if $meta->has_method($method_name);
768 }
769 return @methods;
770}
771
772
# spent 5.06ms (979µs+4.08) within Class::MOP::Class::find_next_method_by_name which was called 69 times, avg 73µs/call: # 36 times (588µs+2.18ms) by Class::MOP::Class::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Class/MOP/Class.pm:678] at line 657, avg 77µs/call # 33 times (391µs+1.91ms) by Class::MOP::Method::Inlined::can_be_inlined at line 40 of Class/MOP/Method/Inlined.pm, avg 70µs/call
sub find_next_method_by_name {
773576711µs my ($self, $method_name) = @_;
774 (defined $method_name && length $method_name)
775 || confess "You must define a method name to find";
776 my @cpl = $self->linearized_isa;
# spent 438µs making 69 calls to Class::MOP::Class::linearized_isa, avg 6µs/call
777 shift @cpl; # discard ourselves
778 foreach my $class (@cpl) {
779 my $method = $self->initialize($class)->get_method($method_name);
# spent 3.08ms making 114 calls to Class::MOP::Mixin::HasMethods::get_method, avg 27µs/call # spent 552µs making 112 calls to Class::MOP::Class::initialize, avg 5µs/call # spent 9µs making 2 calls to Moose::Meta::Class::initialize, avg 4µs/call
780 return $method if defined $method;
781 }
782 return;
783}
784
785
# spent 8µs within Class::MOP::Class::update_meta_instance_dependencies which was called 3 times, avg 3µs/call: # 3 times (8µs+0s) by Class::MOP::Class::_superclasses_updated at line 587, avg 3µs/call
sub update_meta_instance_dependencies {
786610µs my $self = shift;
787
788 if ( $self->{meta_instance_dependencies} ) {
789 return $self->add_meta_instance_dependencies;
790 }
791}
792
793sub add_meta_instance_dependencies {
794 my $self = shift;
795
796 $self->remove_meta_instance_dependencies;
797
798 my @attrs = $self->get_all_attributes();
799
800 my %seen;
801 my @classes = grep { not $seen{ $_->name }++ }
802 map { $_->associated_class } @attrs;
803
804 foreach my $class (@classes) {
805 $class->add_dependent_meta_instance($self);
806 }
807
808 $self->{meta_instance_dependencies} = \@classes;
809}
810
811sub remove_meta_instance_dependencies {
812 my $self = shift;
813
814 if ( my $classes = delete $self->{meta_instance_dependencies} ) {
815 foreach my $class (@$classes) {
816 $class->remove_dependent_meta_instance($self);
817 }
818
819 return $classes;
820 }
821
822 return;
823
824}
825
826sub add_dependent_meta_instance {
827 my ( $self, $metaclass ) = @_;
828 push @{ $self->{dependent_meta_instances} }, $metaclass;
829}
830
831sub remove_dependent_meta_instance {
832 my ( $self, $metaclass ) = @_;
833 my $name = $metaclass->name;
834 @$_ = grep { $_->name ne $name } @$_
835 for $self->{dependent_meta_instances};
836}
837
838
# spent 780µs (628+152) within Class::MOP::Class::invalidate_meta_instances which was called 119 times, avg 7µs/call: # 119 times (628µs+152µs) by Class::MOP::Class::_post_add_attribute at line 509, avg 7µs/call
sub invalidate_meta_instances {
839357533µs my $self = shift;
840 $_->invalidate_meta_instance()
841 for $self, @{ $self->{dependent_meta_instances} };
# spent 152µs making 119 calls to Class::MOP::Class::invalidate_meta_instance, avg 1µs/call
842}
843
844
# spent 152µs within Class::MOP::Class::invalidate_meta_instance which was called 119 times, avg 1µs/call: # 119 times (152µs+0s) by Class::MOP::Class::invalidate_meta_instances at line 841, avg 1µs/call
sub invalidate_meta_instance {
845238261µs my $self = shift;
846 undef $self->{_meta_instance};
847}
848
849# check if we can reinitialize
850sub is_pristine {
851 my $self = shift;
852
853 # if any local attr is defined
854 return if $self->get_attribute_list;
855
856 # or any non-declared methods
857 for my $method ( map { $self->get_method($_) } $self->get_method_list ) {
858 return if $method->isa("Class::MOP::Method::Generated");
859 # FIXME do we need to enforce this too? return unless $method->isa( $self->method_metaclass );
860 }
861
862 return 1;
863}
864
865## Class closing
866
86782123µs
# spent 54µs within Class::MOP::Class::is_mutable which was called 82 times, avg 662ns/call: # 51 times (36µs+0s) by Class::MOP::Class::make_immutable at line 891, avg 710ns/call # 22 times (12µs+0s) by SimpleDB::Client::BEGIN@46 at line 239 of Moose.pm, avg 564ns/call # 9 times (6µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 631 of Moose/Util/TypeConstraints.pm, avg 633ns/call
sub is_mutable { 1 }
868620µs
# spent 7µs within Class::MOP::Class::is_immutable which was called 6 times, avg 1µs/call: # 3 times (4µs+0s) by Class::MOP::Class::_construct_class_instance at line 71, avg 1µs/call # once (1µs+0s) by Moose::Meta::Class::_superclass_meta_is_compatible at line 373 of Moose/Meta/Class.pm # once (800ns+0s) by Class::MOP::Class::_immutable_metaclass at line 956 # once (700ns+0s) by Class::MOP::Class::_check_metaclass_compatibility at line 185
sub is_immutable { 0 }
869
870sub immutable_options { %{ $_[0]{__immutable}{options} || {} } }
871
872
# spent 881µs (618+264) within Class::MOP::Class::_immutable_options which was called 51 times, avg 17µs/call: # 50 times (596µs+251µs) by Class::MOP::Class::make_immutable at line 892, avg 17µs/call # once (22µs+13µs) by Moose::Meta::Class::_immutable_options at line 74 of Moose/Meta/Class.pm
sub _immutable_options {
873102465µs my ( $self, @args ) = @_;
874
875 return (
876 inline_accessors => 1,
# spent 80µs making 50 calls to Class::MOP::Class::immutable_trait, avg 2µs/call # spent 67µs making 51 calls to Class::MOP::Class::constructor_name, avg 1µs/call # spent 59µs making 50 calls to Class::MOP::Class::constructor_class, avg 1µs/call # spent 47µs making 50 calls to Class::MOP::Class::destructor_class, avg 936ns/call # spent 4µs making 1 call to Moose::Meta::Class::immutable_trait # spent 3µs making 1 call to Moose::Meta::Class::constructor_class # spent 3µs making 1 call to Moose::Meta::Class::destructor_class
877 inline_constructor => 1,
878 inline_destructor => 0,
879 debug => 0,
880 immutable_trait => $self->immutable_trait,
881 constructor_name => $self->constructor_name,
882 constructor_class => $self->constructor_class,
883 destructor_class => $self->destructor_class,
884 @args,
885 );
886}
887
888
# spent 86.6ms (731µs+85.9) within Class::MOP::Class::make_immutable which was called 51 times, avg 1.70ms/call: # 22 times (323µs+36.5ms) by SimpleDB::Client::BEGIN@46 at line 244 of Moose.pm, avg 1.68ms/call # 12 times (146µs+13.4ms) by Moose::Exporter::BEGIN@11 at line 678 of Class/MOP.pm, avg 1.13ms/call # 9 times (134µs+16.6ms) by Moose::Meta::Attribute::BEGIN@18 at line 636 of Moose/Util/TypeConstraints.pm, avg 1.86ms/call # 4 times (52µs+399µs) by Moose::Exporter::BEGIN@11 at line 701 of Class/MOP.pm, avg 113µs/call # 2 times (34µs+-34µs) by Class::MOP::Class::_immutable_metaclass at line 979, avg 0s/call # once (25µs+14.2ms) by main::BEGIN@2 at line 332 of ../lib/SimpleDB/Client.pm # once (18µs+4.85ms) by SimpleDB::Client::BEGIN@46 at line 276 of Moose.pm
sub make_immutable {
889255575µs my ( $self, @args ) = @_;
890
891 if ( $self->is_mutable ) {
# spent 36µs making 51 calls to Class::MOP::Class::is_mutable, avg 710ns/call
892 $self->_initialize_immutable( $self->_immutable_options(@args) );
# spent 58.1ms making 51 calls to Class::MOP::Class::_initialize_immutable, avg 1.14ms/call # spent 847µs making 50 calls to Class::MOP::Class::_immutable_options, avg 17µs/call # spent 45µs making 1 call to Moose::Meta::Class::_immutable_options
893 $self->_rebless_as_immutable(@args);
# spent 27.1ms making 51 calls to Class::MOP::Class::_rebless_as_immutable, avg 532µs/call, recursion: max depth 1, time 177µs
894 return $self;
895 }
896 else {
897 return;
898 }
899}
900
901sub make_mutable {
902 my $self = shift;
903
904 if ( $self->is_immutable ) {
905 my @args = $self->immutable_options;
906 $self->_rebless_as_mutable();
907 $self->_remove_inlined_code(@args);
908 delete $self->{__immutable};
909 return $self;
910 }
911 else {
912 return;
913 }
914}
915
916
# spent 27.0ms (383µs+26.6) within Class::MOP::Class::_rebless_as_immutable which was called 51 times, avg 529µs/call: # 51 times (383µs+26.6ms) by Class::MOP::Class::make_immutable at line 893, avg 529µs/call
sub _rebless_as_immutable {
917153349µs my ( $self, @args ) = @_;
918
919 $self->{__immutable}{original_class} = ref $self;
920
921 bless $self => $self->_immutable_metaclass(@args);
# spent 26.8ms making 51 calls to Class::MOP::Class::_immutable_metaclass, avg 525µs/call, recursion: max depth 1, time 147µs
922}
923
924
# spent 26.6ms (1.30+25.3) within Class::MOP::Class::_immutable_metaclass which was called 51 times, avg 522µs/call: # 51 times (1.30ms+25.3ms) by Class::MOP::Class::_rebless_as_immutable at line 921, avg 522µs/call
sub _immutable_metaclass {
9255101.20ms my ( $self, %args ) = @_;
926
927 if ( my $class = $args{immutable_metaclass} ) {
928 return $class;
929 }
930
931 my $trait = $args{immutable_trait} = $self->immutable_trait
# spent 58µs making 50 calls to Class::MOP::Class::immutable_trait, avg 1µs/call # spent 2µs making 1 call to Moose::Meta::Class::immutable_trait
932 || confess "no immutable trait specified for $self";
933
934 my $meta = $self->meta;
# spent 556µs making 51 calls to Class::MOP::Object::meta, avg 11µs/call
935 my $meta_attr = $meta->find_attribute_by_name("immutable_trait");
# spent 1.67ms making 51 calls to Class::MOP::Class::find_attribute_by_name, avg 33µs/call
936
937 my $class_name;
938
939 if ( $meta_attr and $trait eq $meta_attr->default ) {
# spent 111µs making 51 calls to Class::MOP::Mixin::AttributeCore::default, avg 2µs/call
940 # if the trait is the same as the default we try and pick a
941 # predictable name for the immutable metaclass
942 $class_name = 'Class::MOP::Class::Immutable::' . ref($self);
943 }
944 else {
945 $class_name = join '::', 'Class::MOP::Class::Immutable::CustomTrait',
946 $trait, 'ForMetaClass', ref($self);
947 }
948
949 return $class_name
# spent 130µs making 51 calls to Class::MOP::is_class_loaded, avg 3µs/call
950 if Class::MOP::is_class_loaded($class_name);
951
952 # If the metaclass is a subclass of CMOP::Class which has had
953 # metaclass roles applied (via Moose), then we want to make sure
954 # that we preserve that anonymous class (see Fey::ORM for an
955 # example of where this matters).
956 my $meta_name
957 = $meta->is_immutable
958 ? $meta->_get_mutable_metaclass_name
959 : ref $meta;
960
961 my $immutable_meta = $meta_name->create(
# spent 550µs making 2 calls to Class::MOP::Class::create, avg 275µs/call
962 $class_name,
963 superclasses => [ ref $self ],
964 );
965
966 Class::MOP::load_class($trait);
# spent 888µs making 2 calls to Class::MOP::load_class, avg 444µs/call
967 for my $meth ( Class::MOP::Class->initialize($trait)->get_all_methods ) {
# spent 3.74ms making 2 calls to Class::MOP::Class::get_all_methods, avg 1.87ms/call # spent 91µs making 2 calls to Class::MOP::Class::initialize, avg 45µs/call
968 my $meth_name = $meth->name;
# spent 27µs making 42 calls to Class::MOP::Method::name, avg 648ns/call
969
970 if ( $immutable_meta->find_method_by_name( $meth_name ) ) {
# spent 8.56ms making 36 calls to Class::MOP::Class::add_around_method_modifier, avg 238µs/call # spent 6.85ms making 42 calls to Class::MOP::Class::find_method_by_name, avg 163µs/call # spent 23µs making 36 calls to Class::MOP::Method::body, avg 633ns/call
971 $immutable_meta->add_around_method_modifier( $meth_name, $meth->body );
972 }
973 else {
974 $immutable_meta->add_method( $meth_name, $meth->clone );
# spent 1.07ms making 6 calls to Class::MOP::Mixin::HasMethods::add_method, avg 179µs/call # spent 816µs making 6 calls to Class::MOP::Method::clone, avg 136µs/call
975 }
976 }
977
978 $immutable_meta->make_immutable(
979 inline_constructor => 0,
# spent 298µs making 2 calls to Class::MOP::Class::make_immutable, avg 149µs/call, recursion: max depth 1, time 298µs
980 inline_accessors => 0,
981 );
982
983 return $class_name;
984}
985
986sub _remove_inlined_code {
987 my $self = shift;
988
989 $self->remove_method( $_->name ) for $self->_inlined_methods;
990
991 delete $self->{__immutable}{inlined_methods};
992}
993
994sub _inlined_methods { @{ $_[0]{__immutable}{inlined_methods} || [] } }
995
996
# spent 91µs within Class::MOP::Class::_add_inlined_method which was called 33 times, avg 3µs/call: # 32 times (89µs+0s) by Class::MOP::Class::_inline_constructor at line 1065, avg 3µs/call # once (2µs+0s) by Class::MOP::Class::_inline_destructor at line 1098
sub _add_inlined_method {
99766111µs my ( $self, $method ) = @_;
998
999 push @{ $self->{__immutable}{inlined_methods} ||= [] }, $method;
1000}
1001
1002
# spent 58.1ms (514µs+57.6) within Class::MOP::Class::_initialize_immutable which was called 51 times, avg 1.14ms/call: # 51 times (514µs+57.6ms) by Class::MOP::Class::make_immutable at line 892, avg 1.14ms/call
sub _initialize_immutable {
1003153486µs my ( $self, %args ) = @_;
1004
1005 $self->{__immutable}{options} = \%args;
1006 $self->_install_inlined_code(%args);
# spent 57.6ms making 51 calls to Class::MOP::Class::_install_inlined_code, avg 1.13ms/call
1007}
1008
1009
# spent 57.6ms (457µs+57.1) within Class::MOP::Class::_install_inlined_code which was called 51 times, avg 1.13ms/call: # 51 times (457µs+57.1ms) by Class::MOP::Class::_initialize_immutable at line 1006, avg 1.13ms/call
sub _install_inlined_code {
1010204423µs my ( $self, %args ) = @_;
1011
1012 # FIXME
1013 $self->_inline_accessors(%args) if $args{inline_accessors};
# spent 23.4ms making 32 calls to Class::MOP::Class::_inline_accessors, avg 732µs/call
1014 $self->_inline_constructor(%args) if $args{inline_constructor};
# spent 33.0ms making 32 calls to Class::MOP::Class::_inline_constructor, avg 1.03ms/call
1015 $self->_inline_destructor(%args) if $args{inline_destructor};
# spent 764µs making 1 call to Class::MOP::Class::_inline_destructor
1016}
1017
1018sub _rebless_as_mutable {
1019 my $self = shift;
1020
1021 bless $self, $self->_get_mutable_metaclass_name;
1022
1023 return $self;
1024}
1025
1026
# spent 23.4ms (453µs+23.0) within Class::MOP::Class::_inline_accessors which was called 32 times, avg 732µs/call: # 32 times (453µs+23.0ms) by Class::MOP::Class::_install_inlined_code at line 1013, avg 732µs/call
sub _inline_accessors {
1027132309µs my $self = shift;
1028
1029 foreach my $attr_name ( $self->get_attribute_list ) {
# spent 186µs making 32 calls to Class::MOP::Mixin::HasAttributes::get_attribute_list, avg 6µs/call
1030 $self->get_attribute($attr_name)->install_accessors(1);
# spent 21.3ms making 67 calls to Class::MOP::Attribute::install_accessors, avg 318µs/call # spent 1.09ms making 1 call to Moose::Meta::Attribute::install_accessors # spent 363µs making 68 calls to Class::MOP::Mixin::HasAttributes::get_attribute, avg 5µs/call
1031 }
1032}
1033
1034
# spent 33.0ms (749µs+32.2) within Class::MOP::Class::_inline_constructor which was called 32 times, avg 1.03ms/call: # 32 times (749µs+32.2ms) by Class::MOP::Class::_install_inlined_code at line 1014, avg 1.03ms/call
sub _inline_constructor {
1035320592µs my ( $self, %args ) = @_;
1036
1037 my $name = $args{constructor_name};
1038 # A class may not even have a constructor, and that's okay.
1039 return unless defined $name;
1040
1041 if ( $self->has_method($name) && !$args{replace_constructor} ) {
# spent 1.10ms making 32 calls to Class::MOP::Mixin::HasMethods::has_method, avg 34µs/call
1042 my $class = $self->name;
1043 warn "Not inlining a constructor for $class since it defines"
1044 . " its own constructor.\n"
1045 . "If you are certain you don't need to inline your"
1046 . " constructor, specify inline_constructor => 0 in your"
1047 . " call to $class->meta->make_immutable\n";
1048 return;
1049 }
1050
1051 my $constructor_class = $args{constructor_class};
1052
1053 Class::MOP::load_class($constructor_class);
# spent 994µs making 32 calls to Class::MOP::load_class, avg 31µs/call
1054
1055 my $constructor = $constructor_class->new(
# spent 23.9ms making 31 calls to Class::MOP::Method::Constructor::new, avg 772µs/call # spent 1.70ms making 1 call to Moose::Meta::Method::Constructor::new # spent 20µs making 32 calls to Class::MOP::Package::name, avg 616ns/call
1056 options => \%args,
1057 metaclass => $self,
1058 is_inline => 1,
1059 package_name => $self->name,
1060 name => $name,
1061 );
1062
1063 if ( $args{replace_constructor} or $constructor->can_be_inlined ) {
# spent 2.95ms making 32 calls to Class::MOP::Method::Inlined::can_be_inlined, avg 92µs/call
1064 $self->add_method( $name => $constructor );
# spent 1.43ms making 32 calls to Class::MOP::Mixin::HasMethods::add_method, avg 45µs/call
1065 $self->_add_inlined_method($constructor);
# spent 89µs making 32 calls to Class::MOP::Class::_add_inlined_method, avg 3µs/call
1066 }
1067}
1068
1069
# spent 764µs (46+719) within Class::MOP::Class::_inline_destructor which was called # once (46µs+719µs) by Class::MOP::Class::_install_inlined_code at line 1015
sub _inline_destructor {
10701035µs my ( $self, %args ) = @_;
1071
1072 ( exists $args{destructor_class} && defined $args{destructor_class} )
1073 || confess "The 'inline_destructor' option is present, but "
1074 . "no destructor class was specified";
1075
1076 if ( $self->has_method('DESTROY') && ! $args{replace_destructor} ) {
# spent 31µs making 1 call to Class::MOP::Mixin::HasMethods::has_method
1077 my $class = $self->name;
1078 warn "Not inlining a destructor for $class since it defines"
1079 . " its own destructor.\n";
1080 return;
1081 }
1082
1083 my $destructor_class = $args{destructor_class};
1084
1085 Class::MOP::load_class($destructor_class);
# spent 27µs making 1 call to Class::MOP::load_class
1086
1087 return unless $destructor_class->is_needed($self);
# spent 131µs making 1 call to Moose::Meta::Method::Destructor::is_needed
1088
1089 my $destructor = $destructor_class->new(
# spent 350µs making 1 call to Moose::Meta::Method::Destructor::new # spent 700ns making 1 call to Class::MOP::Package::name
1090 options => \%args,
1091 metaclass => $self,
1092 package_name => $self->name,
1093 name => 'DESTROY'
1094 );
1095
1096 if ( $args{replace_destructor} or $destructor->can_be_inlined ) {
# spent 126µs making 1 call to Class::MOP::Method::Inlined::can_be_inlined
1097 $self->add_method( 'DESTROY' => $destructor );
# spent 51µs making 1 call to Class::MOP::Mixin::HasMethods::add_method
1098 $self->_add_inlined_method($destructor);
# spent 2µs making 1 call to Class::MOP::Class::_add_inlined_method
1099 }
1100}
1101
110217µs1;
1103
1104__END__
1105
1106=pod
1107
1108=head1 NAME
1109
1110Class::MOP::Class - Class Meta Object
1111
1112=head1 SYNOPSIS
1113
1114 # assuming that class Foo
1115 # has been defined, you can
1116
1117 # use this for introspection ...
1118
1119 # add a method to Foo ...
1120 Foo->meta->add_method( 'bar' => sub {...} )
1121
1122 # get a list of all the classes searched
1123 # the method dispatcher in the correct order
1124 Foo->meta->class_precedence_list()
1125
1126 # remove a method from Foo
1127 Foo->meta->remove_method('bar');
1128
1129 # or use this to actually create classes ...
1130
1131 Class::MOP::Class->create(
1132 'Bar' => (
1133 version => '0.01',
1134 superclasses => ['Foo'],
1135 attributes => [
1136 Class::MOP::Attribute->new('$bar'),
1137 Class::MOP::Attribute->new('$baz'),
1138 ],
1139 methods => {
1140 calculate_bar => sub {...},
1141 construct_baz => sub {...}
1142 }
1143 )
1144 );
1145
1146=head1 DESCRIPTION
1147
1148The Class Protocol is the largest and most complex part of the
1149Class::MOP meta-object protocol. It controls the introspection and
1150manipulation of Perl 5 classes, and it can create them as well. The
1151best way to understand what this module can do is to read the
1152documentation for each of its methods.
1153
1154=head1 INHERITANCE
1155
1156C<Class::MOP::Class> is a subclass of L<Class::MOP::Module>.
1157
1158=head1 METHODS
1159
1160=head2 Class construction
1161
1162These methods all create new C<Class::MOP::Class> objects. These
1163objects can represent existing classes or they can be used to create
1164new classes from scratch.
1165
1166The metaclass object for a given class is a singleton. If you attempt
1167to create a metaclass for the same class twice, you will just get the
1168existing object.
1169
1170=over 4
1171
1172=item B<< Class::MOP::Class->create($package_name, %options) >>
1173
1174This method creates a new C<Class::MOP::Class> object with the given
1175package name. It accepts a number of options:
1176
1177=over 8
1178
1179=item * version
1180
1181An optional version number for the newly created package.
1182
1183=item * authority
1184
1185An optional authority for the newly created package.
1186
1187=item * superclasses
1188
1189An optional array reference of superclass names.
1190
1191=item * methods
1192
1193An optional hash reference of methods for the class. The keys of the
1194hash reference are method names and values are subroutine references.
1195
1196=item * attributes
1197
1198An optional array reference of L<Class::MOP::Attribute> objects.
1199
1200=back
1201
1202=item B<< Class::MOP::Class->create_anon_class(%options) >>
1203
1204This method works just like C<< Class::MOP::Class->create >> but it
1205creates an "anonymous" class. In fact, the class does have a name, but
1206that name is a unique name generated internally by this module.
1207
1208It accepts the same C<superclasses>, C<methods>, and C<attributes>
1209parameters that C<create> accepts.
1210
1211Anonymous classes are destroyed once the metaclass they are attached
1212to goes out of scope, and will be removed from Perl's internal symbol
1213table.
1214
1215All instances of an anonymous class keep a special reference to the
1216metaclass object, which prevents the metaclass from going out of scope
1217while any instances exist.
1218
1219This only works if the instance is based on a hash reference, however.
1220
1221=item B<< Class::MOP::Class->initialize($package_name, %options) >>
1222
1223This method will initialize a C<Class::MOP::Class> object for the
1224named package. Unlike C<create>, this method I<will not> create a new
1225class.
1226
1227The purpose of this method is to retrieve a C<Class::MOP::Class>
1228object for introspecting an existing class.
1229
1230If an existing C<Class::MOP::Class> object exists for the named
1231package, it will be returned, and any options provided will be
1232ignored!
1233
1234If the object does not yet exist, it will be created.
1235
1236The valid options that can be passed to this method are
1237C<attribute_metaclass>, C<method_metaclass>,
1238C<wrapped_method_metaclass>, and C<instance_metaclass>. These are all
1239optional, and default to the appropriate class in the C<Class::MOP>
1240distribution.
1241
1242=back
1243
1244=head2 Object instance construction and cloning
1245
1246These methods are all related to creating and/or cloning object
1247instances.
1248
1249=over 4
1250
1251=item B<< $metaclass->clone_object($instance, %params) >>
1252
1253This method clones an existing object instance. Any parameters you
1254provide are will override existing attribute values in the object.
1255
1256This is a convenience method for cloning an object instance, then
1257blessing it into the appropriate package.
1258
1259You could implement a clone method in your class, using this method:
1260
1261 sub clone {
1262 my ($self, %params) = @_;
1263 $self->meta->clone_object($self, %params);
1264 }
1265
1266=item B<< $metaclass->rebless_instance($instance, %params) >>
1267
1268This method changes the class of C<$instance> to the metaclass's class.
1269
1270You can only rebless an instance into a subclass of its current
1271class. If you pass any additional parameters, these will be treated
1272like constructor parameters and used to initialize the object's
1273attributes. Any existing attributes that are already set will be
1274overwritten.
1275
1276Before reblessing the instance, this method will call
1277C<rebless_instance_away> on the instance's current metaclass. This method
1278will be passed the instance, the new metaclass, and any parameters
1279specified to C<rebless_instance>. By default, C<rebless_instance_away>
1280does nothing; it is merely a hook.
1281
1282=item B<< $metaclass->rebless_instance_back($instance) >>
1283
1284Does the same thing as C<rebless_instance>, except that you can only
1285rebless an instance into one of its superclasses. Any attributes that
1286do not exist in the superclass will be deinitialized.
1287
1288This is a much more dangerous operation than C<rebless_instance>,
1289especially when multiple inheritance is involved, so use this carefully!
1290
1291=item B<< $metaclass->new_object(%params) >>
1292
1293This method is used to create a new object of the metaclass's
1294class. Any parameters you provide are used to initialize the
1295instance's attributes. A special C<__INSTANCE__> key can be passed to
1296provide an already generated instance, rather than having Class::MOP
1297generate it for you. This is mostly useful for using Class::MOP with
1298foreign classes which generate instances using their own constructors.
1299
1300=item B<< $metaclass->instance_metaclass >>
1301
1302Returns the class name of the instance metaclass. See
1303L<Class::MOP::Instance> for more information on the instance
1304metaclass.
1305
1306=item B<< $metaclass->get_meta_instance >>
1307
1308Returns an instance of the C<instance_metaclass> to be used in the
1309construction of a new instance of the class.
1310
1311=back
1312
1313=head2 Informational predicates
1314
1315These are a few predicate methods for asking information about the
1316class itself.
1317
1318=over 4
1319
1320=item B<< $metaclass->is_anon_class >>
1321
1322This returns true if the class was created by calling C<<
1323Class::MOP::Class->create_anon_class >>.
1324
1325=item B<< $metaclass->is_mutable >>
1326
1327This returns true if the class is still mutable.
1328
1329=item B<< $metaclass->is_immutable >>
1330
1331This returns true if the class has been made immutable.
1332
1333=item B<< $metaclass->is_pristine >>
1334
1335A class is I<not> pristine if it has non-inherited attributes or if it
1336has any generated methods.
1337
1338=back
1339
1340=head2 Inheritance Relationships
1341
1342=over 4
1343
1344=item B<< $metaclass->superclasses(@superclasses) >>
1345
1346This is a read-write accessor which represents the superclass
1347relationships of the metaclass's class.
1348
1349This is basically sugar around getting and setting C<@ISA>.
1350
1351=item B<< $metaclass->class_precedence_list >>
1352
1353This returns a list of all of the class's ancestor classes. The
1354classes are returned in method dispatch order.
1355
1356=item B<< $metaclass->linearized_isa >>
1357
1358This returns a list based on C<class_precedence_list> but with all
1359duplicates removed.
1360
1361=item B<< $metaclass->subclasses >>
1362
1363This returns a list of all subclasses for this class, even indirect
1364subclasses.
1365
1366=item B<< $metaclass->direct_subclasses >>
1367
1368This returns a list of immediate subclasses for this class, which does not
1369include indirect subclasses.
1370
1371=back
1372
1373=head2 Method introspection
1374
1375See L<Class::MOP::Package/Method introspection and creation> for
1376methods that operate only on the current class. Class::MOP::Class adds
1377introspection capabilities that take inheritance into account.
1378
1379=over 4
1380
1381=item B<< $metaclass->get_all_methods >>
1382
1383This will traverse the inheritance hierarchy and return a list of all
1384the L<Class::MOP::Method> objects for this class and its parents.
1385
1386=item B<< $metaclass->find_method_by_name($method_name) >>
1387
1388This will return a L<Class::MOP::Method> for the specified
1389C<$method_name>. If the class does not have the specified method, it
1390returns C<undef>
1391
1392Unlike C<get_method>, this method I<will> look for the named method in
1393superclasses.
1394
1395=item B<< $metaclass->get_all_method_names >>
1396
1397This will return a list of method I<names> for all of this class's
1398methods, including inherited methods.
1399
1400=item B<< $metaclass->find_all_methods_by_name($method_name) >>
1401
1402This method looks for the named method in the class and all of its
1403parents. It returns every matching method it finds in the inheritance
1404tree, so it returns a list of methods.
1405
1406Each method is returned as a hash reference with three keys. The keys
1407are C<name>, C<class>, and C<code>. The C<code> key has a
1408L<Class::MOP::Method> object as its value.
1409
1410The list of methods is distinct.
1411
1412=item B<< $metaclass->find_next_method_by_name($method_name) >>
1413
1414This method returns the first method in any superclass matching the
1415given name. It is effectively the method that C<SUPER::$method_name>
1416would dispatch to.
1417
1418=back
1419
1420=head2 Attribute introspection and creation
1421
1422Because Perl 5 does not have a core concept of attributes in classes,
1423we can only return information about attributes which have been added
1424via this class's methods. We cannot discover information about
1425attributes which are defined in terms of "regular" Perl 5 methods.
1426
1427=over 4
1428
1429=item B<< $metaclass->get_attribute($attribute_name) >>
1430
1431This will return a L<Class::MOP::Attribute> for the specified
1432C<$attribute_name>. If the class does not have the specified
1433attribute, it returns C<undef>.
1434
1435NOTE that get_attribute does not search superclasses, for that you
1436need to use C<find_attribute_by_name>.
1437
1438=item B<< $metaclass->has_attribute($attribute_name) >>
1439
1440Returns a boolean indicating whether or not the class defines the
1441named attribute. It does not include attributes inherited from parent
1442classes.
1443
1444=item B<< $metaclass->get_attribute_list >>
1445
1446This will return a list of attributes I<names> for all attributes
1447defined in this class.
1448
1449=item B<< $metaclass->get_all_attributes >>
1450
1451This will traverse the inheritance hierarchy and return a list of all
1452the L<Class::MOP::Attribute> objects for this class and its parents.
1453
1454=item B<< $metaclass->find_attribute_by_name($attribute_name) >>
1455
1456This will return a L<Class::MOP::Attribute> for the specified
1457C<$attribute_name>. If the class does not have the specified
1458attribute, it returns C<undef>.
1459
1460Unlike C<get_attribute>, this attribute I<will> look for the named
1461attribute in superclasses.
1462
1463=item B<< $metaclass->add_attribute(...) >>
1464
1465This method accepts either an existing L<Class::MOP::Attribute>
1466object or parameters suitable for passing to that class's C<new>
1467method.
1468
1469The attribute provided will be added to the class.
1470
1471Any accessor methods defined by the attribute will be added to the
1472class when the attribute is added.
1473
1474If an attribute of the same name already exists, the old attribute
1475will be removed first.
1476
1477=item B<< $metaclass->remove_attribute($attribute_name) >>
1478
1479This will remove the named attribute from the class, and
1480L<Class::MOP::Attribute> object.
1481
1482Removing an attribute also removes any accessor methods defined by the
1483attribute.
1484
1485However, note that removing an attribute will only affect I<future>
1486object instances created for this class, not existing instances.
1487
1488=item B<< $metaclass->attribute_metaclass >>
1489
1490Returns the class name of the attribute metaclass for this class. By
1491default, this is L<Class::MOP::Attribute>.
1492
1493=back
1494
1495=head2 Class Immutability
1496
1497Making a class immutable "freezes" the class definition. You can no
1498longer call methods which alter the class, such as adding or removing
1499methods or attributes.
1500
1501Making a class immutable lets us optimize the class by inlining some
1502methods, and also allows us to optimize some methods on the metaclass
1503object itself.
1504
1505After immutabilization, the metaclass object will cache most informational
1506methods that returns information about methods or attributes. Methods which
1507would alter the class, such as C<add_attribute> and C<add_method>, will
1508throw an error on an immutable metaclass object.
1509
1510The immutabilization system in L<Moose> takes much greater advantage
1511of the inlining features than Class::MOP itself does.
1512
1513=over 4
1514
1515=item B<< $metaclass->make_immutable(%options) >>
1516
1517This method will create an immutable transformer and use it to make
1518the class and its metaclass object immutable.
1519
1520This method accepts the following options:
1521
1522=over 8
1523
1524=item * inline_accessors
1525
1526=item * inline_constructor
1527
1528=item * inline_destructor
1529
1530These are all booleans indicating whether the specified method(s)
1531should be inlined.
1532
1533By default, accessors and the constructor are inlined, but not the
1534destructor.
1535
1536=item * immutable_trait
1537
1538The name of a class which will be used as a parent class for the
1539metaclass object being made immutable. This "trait" implements the
1540post-immutability functionality of the metaclass (but not the
1541transformation itself).
1542
1543This defaults to L<Class::MOP::Class::Immutable::Trait>.
1544
1545=item * constructor_name
1546
1547This is the constructor method name. This defaults to "new".
1548
1549=item * constructor_class
1550
1551The name of the method metaclass for constructors. It will be used to
1552generate the inlined constructor. This defaults to
1553"Class::MOP::Method::Constructor".
1554
1555=item * replace_constructor
1556
1557This is a boolean indicating whether an existing constructor should be
1558replaced when inlining a constructor. This defaults to false.
1559
1560=item * destructor_class
1561
1562The name of the method metaclass for destructors. It will be used to
1563generate the inlined destructor. This defaults to
1564"Class::MOP::Method::Denstructor".
1565
1566=item * replace_destructor
1567
1568This is a boolean indicating whether an existing destructor should be
1569replaced when inlining a destructor. This defaults to false.
1570
1571=back
1572
1573=item B<< $metaclass->immutable_options >>
1574
1575Returns a hash of the options used when making the class immutable, including
1576both defaults and anything supplied by the user in the call to C<<
1577$metaclass->make_immutable >>. This is useful if you need to temporarily make
1578a class mutable and then restore immutability as it was before.
1579
1580=item B<< $metaclass->make_mutable >>
1581
1582Calling this method reverse the immutabilization transformation.
1583
1584=back
1585
1586=head2 Method Modifiers
1587
1588Method modifiers are hooks which allow a method to be wrapped with
1589I<before>, I<after> and I<around> method modifiers. Every time a
1590method is called, its modifiers are also called.
1591
1592A class can modify its own methods, as well as methods defined in
1593parent classes.
1594
1595=head3 How method modifiers work?
1596
1597Method modifiers work by wrapping the original method and then
1598replacing it in the class's symbol table. The wrappers will handle
1599calling all the modifiers in the appropriate order and preserving the
1600calling context for the original method.
1601
1602The return values of C<before> and C<after> modifiers are
1603ignored. This is because their purpose is B<not> to filter the input
1604and output of the primary method (this is done with an I<around>
1605modifier).
1606
1607This may seem like an odd restriction to some, but doing this allows
1608for simple code to be added at the beginning or end of a method call
1609without altering the function of the wrapped method or placing any
1610extra responsibility on the code of the modifier.
1611
1612Of course if you have more complex needs, you can use the C<around>
1613modifier which allows you to change both the parameters passed to the
1614wrapped method, as well as its return value.
1615
1616Before and around modifiers are called in last-defined-first-called
1617order, while after modifiers are called in first-defined-first-called
1618order. So the call tree might looks something like this:
1619
1620 before 2
1621 before 1
1622 around 2
1623 around 1
1624 primary
1625 around 1
1626 around 2
1627 after 1
1628 after 2
1629
1630=head3 What is the performance impact?
1631
1632Of course there is a performance cost associated with method
1633modifiers, but we have made every effort to make that cost directly
1634proportional to the number of modifier features you use.
1635
1636The wrapping method does its best to B<only> do as much work as it
1637absolutely needs to. In order to do this we have moved some of the
1638performance costs to set-up time, where they are easier to amortize.
1639
1640All this said, our benchmarks have indicated the following:
1641
1642 simple wrapper with no modifiers 100% slower
1643 simple wrapper with simple before modifier 400% slower
1644 simple wrapper with simple after modifier 450% slower
1645 simple wrapper with simple around modifier 500-550% slower
1646 simple wrapper with all 3 modifiers 1100% slower
1647
1648These numbers may seem daunting, but you must remember, every feature
1649comes with some cost. To put things in perspective, just doing a
1650simple C<AUTOLOAD> which does nothing but extract the name of the
1651method called and return it costs about 400% over a normal method
1652call.
1653
1654=over 4
1655
1656=item B<< $metaclass->add_before_method_modifier($method_name, $code) >>
1657
1658This wraps the specified method with the supplied subroutine
1659reference. The modifier will be called as a method itself, and will
1660receive the same arguments as are passed to the method.
1661
1662When the modifier exits, the wrapped method will be called.
1663
1664The return value of the modifier will be ignored.
1665
1666=item B<< $metaclass->add_after_method_modifier($method_name, $code) >>
1667
1668This wraps the specified method with the supplied subroutine
1669reference. The modifier will be called as a method itself, and will
1670receive the same arguments as are passed to the method.
1671
1672When the wrapped methods exits, the modifier will be called.
1673
1674The return value of the modifier will be ignored.
1675
1676=item B<< $metaclass->add_around_method_modifier($method_name, $code) >>
1677
1678This wraps the specified method with the supplied subroutine
1679reference.
1680
1681The first argument passed to the modifier will be a subroutine
1682reference to the wrapped method. The second argument is the object,
1683and after that come any arguments passed when the method is called.
1684
1685The around modifier can choose to call the original method, as well as
1686what arguments to pass if it does so.
1687
1688The return value of the modifier is what will be seen by the caller.
1689
1690=back
1691
1692=head2 Introspection
1693
1694=over 4
1695
1696=item B<< Class::MOP::Class->meta >>
1697
1698This will return a L<Class::MOP::Class> instance for this class.
1699
1700It should also be noted that L<Class::MOP> will actually bootstrap
1701this module by installing a number of attribute meta-objects into its
1702metaclass.
1703
1704=back
1705
1706=head1 AUTHORS
1707
1708Stevan Little E<lt>stevan@iinteractive.comE<gt>
1709
1710=head1 COPYRIGHT AND LICENSE
1711
1712Copyright 2006-2010 by Infinity Interactive, Inc.
1713
1714L<http://www.iinteractive.com>
1715
1716This library is free software; you can redistribute it and/or modify
1717it under the same terms as Perl itself.
1718
1719=cut
# spent 31µs within Class::MOP::Class::CORE:match which was called 67 times, avg 461ns/call: # 67 times (31µs+0s) by Class::MOP::Class::is_anon_class at line 224 of Class/MOP/Class.pm, avg 461ns/call
sub Class::MOP::Class::CORE:match; # xsub
# spent 10µs within Class::MOP::Class::CORE:regcomp which was called # once (10µs+0s) by Class::MOP::Class::is_anon_class at line 224 of Class/MOP/Class.pm
sub Class::MOP::Class::CORE:regcomp; # xsub