Profile of /usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Class/MOP/Class.pm

← 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:22 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
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 11.8ms | 49.2ms | Class::MOP::Class::::BEGIN@15Class::MOP::Class::BEGIN@15
905 | 18 | 8 | 3.79ms | 8.84ms | Class::MOP::Class::::initializeClass::MOP::Class::initialize
85 | 6 | 4 | 2.26ms | 4.82ms | Class::MOP::Class::::get_all_attributesClass::MOP::Class::get_all_attributes
1 | 1 | 1 | 1.63ms | 16.1ms | Class::MOP::Class::::BEGIN@8Class::MOP::Class::BEGIN@8
1 | 1 | 1 | 1.42ms | 1.89ms | Class::MOP::Class::::BEGIN@7Class::MOP::Class::BEGIN@7
1 | 1 | 1 | 1.35ms | 4.16ms | Class::MOP::Class::::BEGIN@9Class::MOP::Class::BEGIN@9
51 | 1 | 1 | 1.30ms | 26.6ms | Class::MOP::Class::::_immutable_metaclassClass::MOP::Class::_immutable_metaclass
119 | 1 | 1 | 1.22ms | 28.9ms | Class::MOP::Class::::_post_add_attributeClass::MOP::Class::_post_add_attribute
1 | 1 | 1 | 1.18ms | 2.41ms | Class::MOP::Class::::BEGIN@10Class::MOP::Class::BEGIN@10
61 | 1 | 1 | 1.04ms | 4.19ms | Class::MOP::Class::::_construct_class_instanceClass::MOP::Class::_construct_class_instance
69 | 2 | 2 | 979µs | 5.06ms | Class::MOP::Class::::find_next_method_by_nameClass::MOP::Class::find_next_method_by_name
217 | 8 | 2 | 979µs | 1.45ms | Class::MOP::Class::::linearized_isaClass::MOP::Class::linearized_isa
51 | 4 | 4 | 958µs | 7.64ms | Class::MOP::Class::::find_method_by_nameClass::MOP::Class::find_method_by_name
32 | 1 | 1 | 749µs | 33.0ms | Class::MOP::Class::::_inline_constructorClass::MOP::Class::_inline_constructor
51 | 7 | 5 | 731µs | 86.6ms | Class::MOP::Class::::make_immutableClass::MOP::Class::make_immutable
119 | 1 | 1 | 707µs | 25.2ms | Class::MOP::Class::::__ANON__[:515]Class::MOP::Class::__ANON__[:515]
59 | 1 | 1 | 657µs | 657µs | Class::MOP::Class::::_newClass::MOP::Class::_new
119 | 1 | 1 | 628µs | 780µs | Class::MOP::Class::::invalidate_meta_instancesClass::MOP::Class::invalidate_meta_instances
36 | 1 | 1 | 623µs | 7.52ms | Class::MOP::Class::::__ANON__[:678]Class::MOP::Class::__ANON__[:678]
51 | 2 | 2 | 618µs | 881µs | Class::MOP::Class::::_immutable_optionsClass::MOP::Class::_immutable_options
51 | 1 | 1 | 522µs | 1.67ms | Class::MOP::Class::::find_attribute_by_nameClass::MOP::Class::find_attribute_by_name
51 | 1 | 1 | 514µs | 58.1ms | Class::MOP::Class::::_initialize_immutableClass::MOP::Class::_initialize_immutable
38 | 1 | 1 | 457µs | 5.52ms | Class::MOP::Class::::_create_meta_instanceClass::MOP::Class::_create_meta_instance
51 | 1 | 1 | 457µs | 57.6ms | Class::MOP::Class::::_install_inlined_codeClass::MOP::Class::_install_inlined_code
32 | 1 | 1 | 453µs | 23.4ms | Class::MOP::Class::::_inline_accessorsClass::MOP::Class::_inline_accessors
51 | 1 | 1 | 383µs | 27.0ms | Class::MOP::Class::::_rebless_as_immutableClass::MOP::Class::_rebless_as_immutable
119 | 1 | 1 | 374µs | 1.36ms | Class::MOP::Class::::_attach_attributeClass::MOP::Class::_attach_attribute
67 | 2 | 1 | 330µs | 416µs | Class::MOP::Class::::is_anon_classClass::MOP::Class::is_anon_class
12 | 1 | 1 | 328µs | 1.24ms | Class::MOP::Class::::_clone_instanceClass::MOP::Class::_clone_instance
270 | 9 | 4 | 321µs | 321µs | Class::MOP::Class::::instance_metaclassClass::MOP::Class::instance_metaclass
64 | 3 | 2 | 302µs | 427µs | Class::MOP::Class::::_check_metaclass_compatibilityClass::MOP::Class::_check_metaclass_compatibility
6 | 2 | 1 | 294µs | 3.27ms | Class::MOP::Class::::_construct_instanceClass::MOP::Class::_construct_instance
36 | 1 | 1 | 259µs | 8.56ms | Class::MOP::Class::::add_around_method_modifierClass::MOP::Class::add_around_method_modifier
7 | 2 | 2 | 179µs | 467µs | Class::MOP::Class::::superclassesClass::MOP::Class::superclasses
63 | 9 | 6 | 177µs | 5.69ms | Class::MOP::Class::::get_meta_instanceClass::MOP::Class::get_meta_instance
2 | 1 | 1 | 155µs | 3.74ms | Class::MOP::Class::::get_all_methodsClass::MOP::Class::get_all_methods
119 | 1 | 1 | 152µs | 152µs | Class::MOP::Class::::invalidate_meta_instanceClass::MOP::Class::invalidate_meta_instance
100 | 2 | 1 | 138µs | 138µs | Class::MOP::Class::::immutable_traitClass::MOP::Class::immutable_trait
12 | 1 | 1 | 130µs | 1.40ms | Class::MOP::Class::::clone_objectClass::MOP::Class::clone_object
33 | 2 | 1 | 91µs | 91µs | Class::MOP::Class::::_add_inlined_methodClass::MOP::Class::_add_inlined_method
2 | 1 | 1 | 79µs | 550µs | Class::MOP::Class::::createClass::MOP::Class::create
51 | 1 | 1 | 67µs | 67µs | Class::MOP::Class::::constructor_nameClass::MOP::Class::constructor_name
50 | 1 | 1 | 59µs | 59µs | Class::MOP::Class::::constructor_classClass::MOP::Class::constructor_class
82 | 3 | 3 | 54µs | 54µs | Class::MOP::Class::::is_mutableClass::MOP::Class::is_mutable
4 | 3 | 3 | 47µs | 1.90ms | Class::MOP::Class::::new_objectClass::MOP::Class::new_object
50 | 1 | 1 | 47µs | 47µs | Class::MOP::Class::::destructor_classClass::MOP::Class::destructor_class
1 | 1 | 1 | 46µs | 764µs | Class::MOP::Class::::_inline_destructorClass::MOP::Class::_inline_destructor
2 | 2 | 2 | 41µs | 187µs | Class::MOP::Class::::find_all_methods_by_nameClass::MOP::Class::find_all_methods_by_name
67 | 1 | 2 | 31µs | 31µs | Class::MOP::Class::::CORE:matchClass::MOP::Class::CORE:match (opcode)
3 | 1 | 1 | 15µs | 23µs | Class::MOP::Class::::_superclasses_updatedClass::MOP::Class::_superclasses_updated
1 | 1 | 1 | 14µs | 78µs | Class::MOP::Class::::BEGIN@16Class::MOP::Class::BEGIN@16
1 | 1 | 1 | 14µs | 17µs | Class::MOP::Class::::BEGIN@4Class::MOP::Class::BEGIN@4
1 | 1 | 1 | 10µs | 3.03ms | Class::MOP::Class::::BEGIN@22Class::MOP::Class::BEGIN@22
1 | 1 | 1 | 10µs | 21µs | Class::MOP::Class::::BEGIN@223Class::MOP::Class::BEGIN@223
1 | 1 | 2 | 10µs | 10µs | Class::MOP::Class::::CORE:regcompClass::MOP::Class::CORE:regcomp (opcode)
1 | 1 | 1 | 9µs | 44µs | Class::MOP::Class::::BEGIN@12Class::MOP::Class::BEGIN@12
1 | 1 | 1 | 9µs | 38µs | Class::MOP::Class::::BEGIN@14Class::MOP::Class::BEGIN@14
1 | 1 | 1 | 9µs | 17µs | Class::MOP::Class::::BEGIN@244Class::MOP::Class::BEGIN@244
1 | 1 | 1 | 8µs | 48µs | Class::MOP::Class::::BEGIN@13Class::MOP::Class::BEGIN@13
1 | 1 | 1 | 8µs | 20µs | Class::MOP::Class::::BEGIN@5Class::MOP::Class::BEGIN@5
3 | 1 | 1 | 8µs | 8µs | Class::MOP::Class::::update_meta_instance_dependenciesClass::MOP::Class::update_meta_instance_dependencies
1 | 1 | 1 | 7µs | 17µs | Class::MOP::Class::::BEGIN@257Class::MOP::Class::BEGIN@257
6 | 4 | 2 | 7µs | 7µs | Class::MOP::Class::::is_immutableClass::MOP::Class::is_immutable
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::DESTROYClass::MOP::Class::DESTROY
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::__ANON__[:305]Class::MOP::Class::__ANON__[:305]
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::__ANON__[:519]Class::MOP::Class::__ANON__[:519]
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::_inlined_methodsClass::MOP::Class::_inlined_methods
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::_rebless_as_mutableClass::MOP::Class::_rebless_as_mutable
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::_remove_inlined_codeClass::MOP::Class::_remove_inlined_code
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::add_after_method_modifierClass::MOP::Class::add_after_method_modifier
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::add_before_method_modifierClass::MOP::Class::add_before_method_modifier
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::add_dependent_meta_instanceClass::MOP::Class::add_dependent_meta_instance
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::add_meta_instance_dependenciesClass::MOP::Class::add_meta_instance_dependencies
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::class_precedence_listClass::MOP::Class::class_precedence_list
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::create_anon_classClass::MOP::Class::create_anon_class
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::direct_subclassesClass::MOP::Class::direct_subclasses
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::get_all_method_namesClass::MOP::Class::get_all_method_names
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::immutable_optionsClass::MOP::Class::immutable_options
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::is_pristineClass::MOP::Class::is_pristine
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::make_mutableClass::MOP::Class::make_mutable
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::rebless_instanceClass::MOP::Class::rebless_instance
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::rebless_instance_awayClass::MOP::Class::rebless_instance_away
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::rebless_instance_backClass::MOP::Class::rebless_instance_back
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::remove_attributeClass::MOP::Class::remove_attribute
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::remove_dependent_meta_instanceClass::MOP::Class::remove_dependent_meta_instance
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::remove_meta_instance_dependenciesClass::MOP::Class::remove_meta_instance_dependencies
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::reset_package_cache_flagClass::MOP::Class::reset_package_cache_flag
0 | 0 | 0 | 0s | 0s | Class::MOP::Class::::subclassesClass::MOP::Class::subclasses
0 | 0 | 0 | 0s | 0s | Class::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 |  |  |  |  |
2 |  |  |  |  | package Class::MOP::Class;
3 |  |  |  |  |
4 | 3 | 20µs | 2 | 20µ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
5 | 3 | 20µs | 2 | 32µ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 |  |  |  |  |
7 | 3 | 104µs | 1 | 1.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
8 | 3 | 129µs | 1 | 16.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
9 | 3 | 153µs | 1 | 4.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
10 | 3 | 138µs | 1 | 2.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 |  |  |  |  |
12 | 3 | 32µs | 2 | 78µ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
13 | 3 | 29µs | 2 | 89µ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
14 | 3 | 29µs | 2 | 67µ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
15 | 3 | 167µs | 2 | 49.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]
16 | 3 | 71µs | 2 | 141µ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 |  |  |  |  |
18 | 1 | 700ns |  |  | our $VERSION = '0.98';
19 | 1 | 14µs |  |  | $VERSION = eval $VERSION;
20 | 1 | 300ns |  |  | our $AUTHORITY = 'cpan:STEVAN';
21 |  |  |  |  |
22 | 3 | 548µs | 2 | 6.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 {
27 | 905 | 246µs |  |  | my $class = shift;
28 |  |  |  |  |
29 | 905 | 71µs |  |  | my $package_name;
30 |  |  |  |  |
31 | 905 | 474µs |  |  | if ( @_ % 2 ) {
32 |  |  |  |  | $package_name = shift;
33 |  |  |  |  | } else {
34 |  |  |  |  | my %options = @_;
35 |  |  |  |  | $package_name = $options{package};
36 |  |  |  |  | }
37 |  |  |  |  |
38 | 905 | 145µs |  |  | ($package_name && !ref($package_name))
39 |  |  |  |  | || confess "You must pass a package name and it cannot be blessed";
40 |  |  |  |  |
41 | 905 | 2.27ms | 966 | 5.17ms | 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 {
52 | 61 | 16µs |  |  | my $class = shift;
53 | 61 | 94µs |  |  | my $options = @_ == 1 ? $_[0] : {@_};
54 | 61 | 24µs |  |  | my $package_name = $options->{package};
55 | 61 | 14µs |  |  | (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 | 61 | 56µs | 61 | 54µs | 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 | 61 | 20µs | 3 | 4µs | $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 | 61 | 6µs |  |  | my $meta;
79 | 61 | 115µs | 59 | 657µs | 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 | 2 | 10µs | 4 | 1.46ms | $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 | 61 | 99µs | 61 | 494µs | $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 | 61 | 59µs | 61 | 102µs | 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 | 61 | 76µs | 61 | 380µs | 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 | 61 | 155µs |  |  | $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 {
104 | 59 | 16µs |  |  | my $class = shift;
105 |  |  |  |  |
106 | 59 | 14µs |  |  | return Class::MOP::Class->initialize($class)->new_object(@_)
107 |  |  |  |  | if $class ne __PACKAGE__;
108 |  |  |  |  |
109 | 59 | 23µs |  |  | my $options = @_ == 1 ? $_[0] : {@_};
110 |  |  |  |  |
111 | 59 | 654µs |  |  | 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 |  |  |  |  |
156 |  |  |  |  | sub reset_package_cache_flag { (shift)->{'_package_cache_flag'} = undef }
157 |  |  |  |  | sub 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 {
169 | 64 | 14µs |  |  | my $self = shift;
170 |  |  |  |  |
171 |  |  |  |  | # this is always okay ...
172 | 64 | 193µs | 61 | 91µs | 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 | 3 | 7µs | 3 | 29µs | my @class_list = $self->linearized_isa; # spent 29µs making 3 calls to Class::MOP::Class::linearized_isa, avg 10µs/call
176 | 3 | 1µs |  |  | shift @class_list; # shift off $self->name
177 |  |  |  |  |
178 | 3 | 9µs |  |  | foreach my $superclass_name (@class_list) {
179 | 1 | 1µs | 1 | 1µs | 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 | 1 | 2µs | 1 | 700ns | 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 | 1 | 3µs | 1 | 600ns | ($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 | 1 | 7µs | 3 | 3µs | ($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.
212 | 2 | 300ns |  |  | 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.
219 | 1 | 400ns |  |  | 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 {
222 | 67 | 16µs |  |  | my $self = shift;
223 | 3 | 86µs | 2 | 32µ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 | 67 | 433µs | 135 | 86µs | $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 |  |  |  |  |
244 | 3 | 69µs | 2 | 26µ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);
257 | 3 | 2.81ms | 2 | 27µ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 {
270 | 2 | 3µs |  |  | my ( $class, @args ) = @_;
271 |  |  |  |  |
272 | 2 | 3µs |  |  | unshift @args, 'package' if @args % 2 == 1;
273 |  |  |  |  |
274 | 2 | 2µs |  |  | my (%options) = @args;
275 | 2 | 2µs |  |  | my $package_name = $options{package};
276 |  |  |  |  |
277 | 2 | 2µs |  |  | (ref $options{superclasses} eq 'ARRAY')
278 |  |  |  |  | || confess "You must pass an ARRAY ref of superclasses"
279 |  |  |  |  | if exists $options{superclasses};
280 |  |  |  |  |
281 | 2 | 1µs |  |  | (ref $options{attributes} eq 'ARRAY')
282 |  |  |  |  | || confess "You must pass an ARRAY ref of attributes"
283 |  |  |  |  | if exists $options{attributes};
284 |  |  |  |  |
285 | 2 | 1µs |  |  | (ref $options{methods} eq 'HASH')
286 |  |  |  |  | || confess "You must pass a HASH ref of methods"
287 |  |  |  |  | if exists $options{methods};
288 |  |  |  |  |
289 | 2 | 2µs |  |  | my (%initialize_options) = @args;
290 | 2 | 3µs |  |  | delete @initialize_options{qw(
291 |  |  |  |  | package
292 |  |  |  |  | superclasses
293 |  |  |  |  | attributes
294 |  |  |  |  | methods
295 |  |  |  |  | version
296 |  |  |  |  | authority
297 |  |  |  |  | )};
298 | 2 | 4µs | 2 | 119µs | 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 | 2 | 12µs | 2 | 74µs | $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 | 2 | 15µs | 2 | 78µs | }); # spent 78µs making 2 calls to Class::MOP::Mixin::HasMethods::add_method, avg 39µs/call
306 |  |  |  |  |
307 | 2 | 7µs | 2 | 201µs | $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 | 2 | 1µs |  |  | if (exists $options{attributes}) {
315 |  |  |  |  | foreach my $attr (@{$options{attributes}}) {
316 |  |  |  |  | $meta->add_attribute($attr);
317 |  |  |  |  | }
318 |  |  |  |  | }
319 | 2 | 1µs |  |  | 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 | 2 | 7µs |  |  | 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 |  |  |  |  |
333 | 270 | 566µ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'} }
334 | 100 | 224µ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'} }
335 | 50 | 95µ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'} }
336 | 51 | 98µ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'} }
337 | 50 | 79µ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 {
342 | 4 | 2µ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 | 4 | 39µs | 8 | 11µs | 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 | 4 | 18µs | 4 | 1.84ms | 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 {
355 | 6 | 2µs |  |  | my $class = shift;
356 | 6 | 4µs |  |  | my $params = @_ == 1 ? $_[0] : {@_};
357 | 6 | 10µs | 6 | 892µs | 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 | 6 | 17µs | 6 | 399µs | 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 | 6 | 17µs | 6 | 491µs | 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 | 84 | 104µs | 84 | 1.16ms | $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 | 6 | 11µs | 6 | 36µs | 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 | 6 | 14µs |  |  | 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 {
383 | 63 | 11µs |  |  | my $self = shift;
384 | 63 | 180µs | 38 | 5.52ms | $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 {
388 | 38 | 5µs |  |  | my $self = shift;
389 |  |  |  |  |
390 | 38 | 181µs | 114 | 5.02ms | 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 | 38 | 54µs | 38 | 36µs | $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 | 38 | 72µs |  |  | 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 {
402 | 12 | 3µs |  |  | my $class = shift;
403 | 12 | 2µs |  |  | my $instance = shift;
404 | 12 | 75µs | 36 | 20µs | (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 | 12 | 36µs | 12 | 11µs | return $instance if $instance->isa('Class::MOP::Class'); # spent 11µs making 12 calls to UNIVERSAL::isa, avg 942ns/call
412 | 12 | 38µs | 12 | 1.24ms | $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 {
416 | 12 | 13µs |  |  | my ($class, $instance, %params) = @_;
417 | 12 | 24µs | 12 | 5µs | (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 | 12 | 15µs | 12 | 167µs | 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 | 12 | 21µs | 12 | 116µs | my $clone = $meta_instance->clone_instance($instance); # spent 116µs making 12 calls to Class::MOP::Instance::clone_instance, avg 10µs/call
421 | 12 | 22µs | 12 | 279µs | 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 | 60 | 105µs | 72 | 342µs | 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 | 12 | 27µs |  |  | return $clone;
429 |  |  |  |  | }
430 |  |  |  |  |
431 |  |  |  |  | sub 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 |  |  |  |  |
468 |  |  |  |  | sub 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 |  |  |  |  |
497 |  |  |  |  | sub 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 {
502 | 119 | 45µs |  |  | my ($self, $attribute) = @_;
503 | 119 | 282µs | 119 | 982µs | $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 {
507 | 119 | 41µs |  |  | my ( $self, $attribute ) = @_;
508 |  |  |  |  |
509 | 119 | 130µs | 119 | 780µs | $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 {
513 | 119 | 231µs |  |  | local $SIG{__DIE__};
514 | 119 | 413µs | 119 | 24.5ms | $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 | 119 | 811µs | 238 | 26.9ms | }; # 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 |  |  |  |  |
522 |  |  |  |  | sub 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 {
537 | 51 | 21µs |  |  | my ( $self, $attr_name ) = @_;
538 |  |  |  |  |
539 | 51 | 76µs | 51 | 442µs | 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 | 51 | 54µs | 51 | 232µs | my $meta = $self->initialize($class); # spent 232µs making 51 calls to Class::MOP::Class::initialize, avg 5µs/call
542 | 51 | 210µs | 102 | 478µs | 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 {
550 | 85 | 14µs |  |  | my $self = shift;
551 | 691 | 1.29ms | 691 | 2.46ms | 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 | 85 | 290µs |  |  | 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 {
559 | 7 | 2µs |  |  | my $self = shift;
560 | 7 | 12µs |  |  | my $var_spec = { sigil => '@', type => 'ARRAY', name => 'ISA' };
561 | 7 | 3µs |  |  | if (@_) {
562 | 3 | 2µs |  |  | my @supers = @_;
563 | 3 | 58µs | 3 | 50µs | @{$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 | 3 | 13µs | 3 | 2µs | my $class = $self->name; # spent 2µs making 3 calls to Class::MOP::Package::name, avg 767ns/call
570 | 3 | 32µs | 3 | 4µs | $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 | 3 | 4µs | 3 | 145µs | $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 | 3 | 9µs | 3 | 23µs | $self->_superclasses_updated(); # spent 23µs making 3 calls to Class::MOP::Class::_superclasses_updated, avg 8µs/call
581 |  |  |  |  | }
582 | 7 | 33µs | 7 | 78µs | @{$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 {
586 | 3 | 1µs |  |  | my $self = shift;
587 | 3 | 13µs | 3 | 8µs | $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 |  |  |  |  |
590 |  |  |  |  | sub subclasses {
591 |  |  |  |  | my $self = shift;
592 |  |  |  |  | my $super_class = $self->name;
593 |  |  |  |  |
594 |  |  |  |  | return @{ $super_class->mro::get_isarev() };
595 |  |  |  |  | }
596 |  |  |  |  |
597 |  |  |  |  | sub 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 {
609 | 217 | 1.64ms | 434 | 473µ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 |  |  |  |  |
612 |  |  |  |  | sub 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 |  |  |  |  | {
649 | 1 | 200ns |  |  | # 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 {
650 | 36 | 12µs |  |  | my ($self, $method_name) = @_;
651 | 36 | 51µs | 36 | 47µs | 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 | 36 | 30µs | 36 | 704µs | 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 | 36 | 16µs |  |  | unless ($method) {
656 |  |  |  |  | # try to find the next method
657 | 36 | 45µs | 36 | 2.77ms | $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 | 36 | 4µs |  |  | (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 | 36 | 142µs | 72 | 1.84ms | $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 | 36 | 78µs | 36 | 1.54ms | $self->add_method($method_name => $method); # spent 1.54ms making 36 calls to Class::MOP::Mixin::HasMethods::add_method, avg 43µs/call
677 | 36 | 79µs |  |  | return $method;
678 | 1 | 2µ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 {
701 | 36 | 19µs |  |  | my ($self, $method_name, $method_modifier) = @_;
702 | 36 | 8µs |  |  | (defined $method_name && length $method_name)
703 |  |  |  |  | || confess "You must pass in a method name";
704 | 36 | 38µs | 36 | 7.52ms | 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 | 36 | 224µs | 72 | 776µs | $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 {
725 | 51 | 20µs |  |  | my ($self, $method_name) = @_;
726 | 51 | 17µs |  |  | (defined $method_name && length $method_name)
727 |  |  |  |  | || confess "You must define a method name to find";
728 | 51 | 78µs | 51 | 341µs | foreach my $class ($self->linearized_isa) { # spent 341µs making 51 calls to Class::MOP::Class::linearized_isa, avg 7µs/call
729 | 179 | 328µs | 358 | 6.35ms | 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 | 179 | 134µs |  |  | return $method if defined $method;
731 |  |  |  |  | }
732 | 13 | 26µs |  |  | 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 {
736 | 2 | 800ns |  |  | my $self = shift;
737 |  |  |  |  |
738 | 2 | 500ns |  |  | my %methods;
739 | 2 | 4µs | 2 | 14µs | for my $class ( reverse $self->linearized_isa ) { # spent 14µs making 2 calls to Class::MOP::Class::linearized_isa, avg 7µs/call
740 | 3 | 5µs | 3 | 16µs | 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 | 6 | 87µs | 45 | 3.55ms | 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 | 2 | 11µs |  |  | return values %methods;
747 |  |  |  |  | }
748 |  |  |  |  |
749 |  |  |  |  | sub 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 {
756 | 2 | 2µs |  |  | my ($self, $method_name) = @_;
757 | 2 | 1µs |  |  | (defined $method_name && length $method_name)
758 |  |  |  |  | || confess "You must define a method name to find";
759 | 2 | 400ns |  |  | my @methods;
760 | 2 | 4µs | 2 | 12µs | 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 | 4 | 4µs | 4 | 17µs | my $meta = $self->initialize($class); # spent 17µs making 4 calls to Moose::Meta::Class::initialize, avg 4µs/call
763 | 4 | 6µs | 4 | 117µs | 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 | 2 | 6µs |  |  | 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 {
773 | 69 | 31µs |  |  | my ($self, $method_name) = @_;
774 | 69 | 23µs |  |  | (defined $method_name && length $method_name)
775 |  |  |  |  | || confess "You must define a method name to find";
776 | 69 | 184µs | 69 | 438µs | my @cpl = $self->linearized_isa; # spent 438µs making 69 calls to Class::MOP::Class::linearized_isa, avg 6µs/call
777 | 69 | 18µs |  |  | shift @cpl; # discard ourselves
778 | 69 | 40µs |  |  | foreach my $class (@cpl) {
779 | 114 | 222µs | 228 | 3.65ms | 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 | 114 | 188µs |  |  | return $method if defined $method;
781 |  |  |  |  | }
782 | 3 | 6µs |  |  | 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 {
786 | 3 | 1µs |  |  | my $self = shift;
787 |  |  |  |  |
788 | 3 | 9µs |  |  | if ( $self->{meta_instance_dependencies} ) {
789 |  |  |  |  | return $self->add_meta_instance_dependencies;
790 |  |  |  |  | }
791 |  |  |  |  | }
792 |  |  |  |  |
793 |  |  |  |  | sub 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 |  |  |  |  |
811 |  |  |  |  | sub 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 |  |  |  |  |
826 |  |  |  |  | sub add_dependent_meta_instance {
827 |  |  |  |  | my ( $self, $metaclass ) = @_;
828 |  |  |  |  | push @{ $self->{dependent_meta_instances} }, $metaclass;
829 |  |  |  |  | }
830 |  |  |  |  |
831 |  |  |  |  | sub 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 {
839 | 119 | 25µs |  |  | my $self = shift;
840 |  |  |  |  | $_->invalidate_meta_instance()
841 | 238 | 509µs | 119 | 152µs | 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 {
845 | 119 | 16µs |  |  | my $self = shift;
846 | 119 | 245µs |  |  | undef $self->{_meta_instance};
847 |  |  |  |  | }
848 |  |  |  |  |
849 |  |  |  |  | # check if we can reinitialize
850 |  |  |  |  | sub 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 |  |  |  |  |
867 | 82 | 123µ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 }
868 | 6 | 20µ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 |  |  |  |  |
870 |  |  |  |  | sub 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 {
873 | 51 | 52µs |  |  | my ( $self, @args ) = @_;
874 |  |  |  |  |
875 |  |  |  |  | return (
876 | 51 | 413µs | 204 | 264µs | 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 {
889 | 51 | 69µs |  |  | my ( $self, @args ) = @_;
890 |  |  |  |  |
891 | 51 | 58µs | 51 | 36µs | if ( $self->is_mutable ) { # spent 36µs making 51 calls to Class::MOP::Class::is_mutable, avg 710ns/call
892 | 51 | 231µs | 102 | 59.0ms | $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 | 51 | 86µs | 51 | 27.0ms | $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 | 51 | 130µs |  |  | return $self;
895 |  |  |  |  | }
896 |  |  |  |  | else {
897 |  |  |  |  | return;
898 |  |  |  |  | }
899 |  |  |  |  | }
900 |  |  |  |  |
901 |  |  |  |  | sub 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 {
917 | 51 | 64µs |  |  | my ( $self, @args ) = @_;
918 |  |  |  |  |
919 | 51 | 41µs |  |  | $self->{__immutable}{original_class} = ref $self;
920 |  |  |  |  |
921 | 51 | 244µs | 51 | 26.6ms | 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 {
925 | 51 | 60µs |  |  | my ( $self, %args ) = @_;
926 |  |  |  |  |
927 | 51 | 22µs |  |  | if ( my $class = $args{immutable_metaclass} ) {
928 |  |  |  |  | return $class;
929 |  |  |  |  | }
930 |  |  |  |  |
931 | 51 | 74µs | 51 | 60µs | 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 | 51 | 67µs | 51 | 556µs | my $meta = $self->meta; # spent 556µs making 51 calls to Class::MOP::Object::meta, avg 11µs/call
935 | 51 | 98µs | 51 | 1.67ms | 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 | 51 | 6µs |  |  | my $class_name;
938 |  |  |  |  |
939 | 51 | 113µs | 51 | 111µs | 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 | 51 | 372µs | 51 | 130µs | 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 | 2 | 8µs | 3 | 15µs | my $meta_name # spent 11µs making 1 call to Class::MOP::Class::Immutable::Class::MOP::Class::is_immutable # spent 4µs making 1 call to Class::MOP::Class::Immutable::Trait::_get_mutable_metaclass_name # spent 800ns making 1 call to Class::MOP::Class::is_immutable
957 |  |  |  |  | = $meta->is_immutable
958 |  |  |  |  | ? $meta->_get_mutable_metaclass_name
959 |  |  |  |  | : ref $meta;
960 |  |  |  |  |
961 | 2 | 8µs | 2 | 550µs | 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 | 2 | 3µs | 2 | 888µs | Class::MOP::load_class($trait); # spent 888µs making 2 calls to Class::MOP::load_class, avg 444µs/call
967 | 2 | 12µs | 4 | 3.83ms | 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 | 42 | 116µs | 42 | 27µs | my $meth_name = $meth->name; # spent 27µs making 42 calls to Class::MOP::Method::name, avg 648ns/call
969 |  |  |  |  |
970 | 42 | 209µs | 114 | 15.4ms | 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 | 6 | 16µs | 12 | 1.89ms | $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 | 2 | 6µs | 2 | 0s | 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 | 2 | 6µs |  |  | return $class_name;
984 |  |  |  |  | }
985 |  |  |  |  |
986 |  |  |  |  | sub _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 |  |  |  |  |
994 |  |  |  |  | sub _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 {
997 | 33 | 15µs |  |  | my ( $self, $method ) = @_;
998 |  |  |  |  |
999 | 33 | 96µs |  |  | 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 {
1003 | 51 | 172µs |  |  | my ( $self, %args ) = @_;
1004 |  |  |  |  |
1005 | 51 | 88µs |  |  | $self->{__immutable}{options} = \%args;
1006 | 51 | 226µs | 51 | 57.6ms | $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 {
1010 | 51 | 98µs |  |  | my ( $self, %args ) = @_;
1011 |  |  |  |  |
1012 |  |  |  |  | # FIXME
1013 | 51 | 87µs | 32 | 23.4ms | $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 | 51 | 94µs | 32 | 33.0ms | $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 | 51 | 143µs | 1 | 764µs | $self->_inline_destructor(%args) if $args{inline_destructor}; # spent 764µs making 1 call to Class::MOP::Class::_inline_destructor
1016 |  |  |  |  | }
1017 |  |  |  |  |
1018 |  |  |  |  | sub _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 {
1027 | 32 | 7µs |  |  | my $self = shift;
1028 |  |  |  |  |
1029 | 32 | 114µs | 32 | 186µs | 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 | 68 | 187µs | 136 | 22.8ms | $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 {
1035 | 32 | 70µs |  |  | my ( $self, %args ) = @_;
1036 |  |  |  |  |
1037 | 32 | 11µs |  |  | my $name = $args{constructor_name};
1038 |  |  |  |  | # A class may not even have a constructor, and that's okay.
1039 | 32 | 5µs |  |  | return unless defined $name;
1040 |  |  |  |  |
1041 | 32 | 46µs | 32 | 1.10ms | 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 | 32 | 13µs |  |  | my $constructor_class = $args{constructor_class};
1052 |  |  |  |  |
1053 | 32 | 31µs | 32 | 994µs | Class::MOP::load_class($constructor_class); # spent 994µs making 32 calls to Class::MOP::load_class, avg 31µs/call
1054 |  |  |  |  |
1055 | 32 | 146µs | 64 | 25.6ms | 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 | 32 | 158µs | 32 | 2.95ms | 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 | 32 | 60µs | 32 | 1.43ms | $self->add_method( $name => $constructor ); # spent 1.43ms making 32 calls to Class::MOP::Mixin::HasMethods::add_method, avg 45µs/call
1065 | 32 | 51µs | 32 | 89µs | $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 {
1070 | 1 | 4µs |  |  | my ( $self, %args ) = @_;
1071 |  |  |  |  |
1072 | 1 | 1µs |  |  | ( 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 | 1 | 2µs | 1 | 31µs | 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 | 1 | 900ns |  |  | my $destructor_class = $args{destructor_class};
1084 |  |  |  |  |
1085 | 1 | 1µs | 1 | 27µs | Class::MOP::load_class($destructor_class); # spent 27µs making 1 call to Class::MOP::load_class
1086 |  |  |  |  |
1087 | 1 | 5µs | 1 | 131µs | return unless $destructor_class->is_needed($self); # spent 131µs making 1 call to Moose::Meta::Method::Destructor::is_needed
1088 |  |  |  |  |
1089 | 1 | 8µs | 2 | 351µs | 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 | 1 | 9µs | 1 | 126µs | if ( $args{replace_destructor} or $destructor->can_be_inlined ) { # spent 126µs making 1 call to Class::MOP::Method::Inlined::can_be_inlined
1097 | 1 | 2µs | 1 | 51µs | $self->add_method( 'DESTROY' => $destructor ); # spent 51µs making 1 call to Class::MOP::Mixin::HasMethods::add_method
1098 | 1 | 2µs | 1 | 2µs | $self->_add_inlined_method($destructor); # spent 2µs making 1 call to Class::MOP::Class::_add_inlined_method
1099 |  |  |  |  | }
1100 |  |  |  |  | }
1101 |  |  |  |  |
1102 | 1 | 7µs |  |  | 1;
1103 |  |  |  |  |
1104 |  |  |  |  | __END__
1105 |  |  |  |  |
1106 |  |  |  |  | =pod
1107 |  |  |  |  |
1108 |  |  |  |  | =head1 NAME
1109 |  |  |  |  |
1110 |  |  |  |  | Class::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 |  |  |  |  |
1148 |  |  |  |  | The Class Protocol is the largest and most complex part of the
1149 |  |  |  |  | Class::MOP meta-object protocol. It controls the introspection and
1150 |  |  |  |  | manipulation of Perl 5 classes, and it can create them as well. The
1151 |  |  |  |  | best way to understand what this module can do is to read the
1152 |  |  |  |  | documentation for each of its methods.
1153 |  |  |  |  |
1154 |  |  |  |  | =head1 INHERITANCE
1155 |  |  |  |  |
1156 |  |  |  |  | C<Class::MOP::Class> is a subclass of L<Class::MOP::Module>.
1157 |  |  |  |  |
1158 |  |  |  |  | =head1 METHODS
1159 |  |  |  |  |
1160 |  |  |  |  | =head2 Class construction
1161 |  |  |  |  |
1162 |  |  |  |  | These methods all create new C<Class::MOP::Class> objects. These
1163 |  |  |  |  | objects can represent existing classes or they can be used to create
1164 |  |  |  |  | new classes from scratch.
1165 |  |  |  |  |
1166 |  |  |  |  | The metaclass object for a given class is a singleton. If you attempt
1167 |  |  |  |  | to create a metaclass for the same class twice, you will just get the
1168 |  |  |  |  | existing object.
1169 |  |  |  |  |
1170 |  |  |  |  | =over 4
1171 |  |  |  |  |
1172 |  |  |  |  | =item B<< Class::MOP::Class->create($package_name, %options) >>
1173 |  |  |  |  |
1174 |  |  |  |  | This method creates a new C<Class::MOP::Class> object with the given
1175 |  |  |  |  | package name. It accepts a number of options:
1176 |  |  |  |  |
1177 |  |  |  |  | =over 8
1178 |  |  |  |  |
1179 |  |  |  |  | =item * version
1180 |  |  |  |  |
1181 |  |  |  |  | An optional version number for the newly created package.
1182 |  |  |  |  |
1183 |  |  |  |  | =item * authority
1184 |  |  |  |  |
1185 |  |  |  |  | An optional authority for the newly created package.
1186 |  |  |  |  |
1187 |  |  |  |  | =item * superclasses
1188 |  |  |  |  |
1189 |  |  |  |  | An optional array reference of superclass names.
1190 |  |  |  |  |
1191 |  |  |  |  | =item * methods
1192 |  |  |  |  |
1193 |  |  |  |  | An optional hash reference of methods for the class. The keys of the
1194 |  |  |  |  | hash reference are method names and values are subroutine references.
1195 |  |  |  |  |
1196 |  |  |  |  | =item * attributes
1197 |  |  |  |  |
1198 |  |  |  |  | An optional array reference of L<Class::MOP::Attribute> objects.
1199 |  |  |  |  |
1200 |  |  |  |  | =back
1201 |  |  |  |  |
1202 |  |  |  |  | =item B<< Class::MOP::Class->create_anon_class(%options) >>
1203 |  |  |  |  |
1204 |  |  |  |  | This method works just like C<< Class::MOP::Class->create >> but it
1205 |  |  |  |  | creates an "anonymous" class. In fact, the class does have a name, but
1206 |  |  |  |  | that name is a unique name generated internally by this module.
1207 |  |  |  |  |
1208 |  |  |  |  | It accepts the same C<superclasses>, C<methods>, and C<attributes>
1209 |  |  |  |  | parameters that C<create> accepts.
1210 |  |  |  |  |
1211 |  |  |  |  | Anonymous classes are destroyed once the metaclass they are attached
1212 |  |  |  |  | to goes out of scope, and will be removed from Perl's internal symbol
1213 |  |  |  |  | table.
1214 |  |  |  |  |
1215 |  |  |  |  | All instances of an anonymous class keep a special reference to the
1216 |  |  |  |  | metaclass object, which prevents the metaclass from going out of scope
1217 |  |  |  |  | while any instances exist.
1218 |  |  |  |  |
1219 |  |  |  |  | This only works if the instance is based on a hash reference, however.
1220 |  |  |  |  |
1221 |  |  |  |  | =item B<< Class::MOP::Class->initialize($package_name, %options) >>
1222 |  |  |  |  |
1223 |  |  |  |  | This method will initialize a C<Class::MOP::Class> object for the
1224 |  |  |  |  | named package. Unlike C<create>, this method I<will not> create a new
1225 |  |  |  |  | class.
1226 |  |  |  |  |
1227 |  |  |  |  | The purpose of this method is to retrieve a C<Class::MOP::Class>
1228 |  |  |  |  | object for introspecting an existing class.
1229 |  |  |  |  |
1230 |  |  |  |  | If an existing C<Class::MOP::Class> object exists for the named
1231 |  |  |  |  | package, it will be returned, and any options provided will be
1232 |  |  |  |  | ignored!
1233 |  |  |  |  |
1234 |  |  |  |  | If the object does not yet exist, it will be created.
1235 |  |  |  |  |
1236 |  |  |  |  | The valid options that can be passed to this method are
1237 |  |  |  |  | C<attribute_metaclass>, C<method_metaclass>,
1238 |  |  |  |  | C<wrapped_method_metaclass>, and C<instance_metaclass>. These are all
1239 |  |  |  |  | optional, and default to the appropriate class in the C<Class::MOP>
1240 |  |  |  |  | distribution.
1241 |  |  |  |  |
1242 |  |  |  |  | =back
1243 |  |  |  |  |
1244 |  |  |  |  | =head2 Object instance construction and cloning
1245 |  |  |  |  |
1246 |  |  |  |  | These methods are all related to creating and/or cloning object
1247 |  |  |  |  | instances.
1248 |  |  |  |  |
1249 |  |  |  |  | =over 4
1250 |  |  |  |  |
1251 |  |  |  |  | =item B<< $metaclass->clone_object($instance, %params) >>
1252 |  |  |  |  |
1253 |  |  |  |  | This method clones an existing object instance. Any parameters you
1254 |  |  |  |  | provide are will override existing attribute values in the object.
1255 |  |  |  |  |
1256 |  |  |  |  | This is a convenience method for cloning an object instance, then
1257 |  |  |  |  | blessing it into the appropriate package.
1258 |  |  |  |  |
1259 |  |  |  |  | You 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 |  |  |  |  |
1268 |  |  |  |  | This method changes the class of C<$instance> to the metaclass's class.
1269 |  |  |  |  |
1270 |  |  |  |  | You can only rebless an instance into a subclass of its current
1271 |  |  |  |  | class. If you pass any additional parameters, these will be treated
1272 |  |  |  |  | like constructor parameters and used to initialize the object's
1273 |  |  |  |  | attributes. Any existing attributes that are already set will be
1274 |  |  |  |  | overwritten.
1275 |  |  |  |  |
1276 |  |  |  |  | Before reblessing the instance, this method will call
1277 |  |  |  |  | C<rebless_instance_away> on the instance's current metaclass. This method
1278 |  |  |  |  | will be passed the instance, the new metaclass, and any parameters
1279 |  |  |  |  | specified to C<rebless_instance>. By default, C<rebless_instance_away>
1280 |  |  |  |  | does nothing; it is merely a hook.
1281 |  |  |  |  |
1282 |  |  |  |  | =item B<< $metaclass->rebless_instance_back($instance) >>
1283 |  |  |  |  |
1284 |  |  |  |  | Does the same thing as C<rebless_instance>, except that you can only
1285 |  |  |  |  | rebless an instance into one of its superclasses. Any attributes that
1286 |  |  |  |  | do not exist in the superclass will be deinitialized.
1287 |  |  |  |  |
1288 |  |  |  |  | This is a much more dangerous operation than C<rebless_instance>,
1289 |  |  |  |  | especially when multiple inheritance is involved, so use this carefully!
1290 |  |  |  |  |
1291 |  |  |  |  | =item B<< $metaclass->new_object(%params) >>
1292 |  |  |  |  |
1293 |  |  |  |  | This method is used to create a new object of the metaclass's
1294 |  |  |  |  | class. Any parameters you provide are used to initialize the
1295 |  |  |  |  | instance's attributes. A special C<__INSTANCE__> key can be passed to
1296 |  |  |  |  | provide an already generated instance, rather than having Class::MOP
1297 |  |  |  |  | generate it for you. This is mostly useful for using Class::MOP with
1298 |  |  |  |  | foreign classes which generate instances using their own constructors.
1299 |  |  |  |  |
1300 |  |  |  |  | =item B<< $metaclass->instance_metaclass >>
1301 |  |  |  |  |
1302 |  |  |  |  | Returns the class name of the instance metaclass. See
1303 |  |  |  |  | L<Class::MOP::Instance> for more information on the instance
1304 |  |  |  |  | metaclass.
1305 |  |  |  |  |
1306 |  |  |  |  | =item B<< $metaclass->get_meta_instance >>
1307 |  |  |  |  |
1308 |  |  |  |  | Returns an instance of the C<instance_metaclass> to be used in the
1309 |  |  |  |  | construction of a new instance of the class.
1310 |  |  |  |  |
1311 |  |  |  |  | =back
1312 |  |  |  |  |
1313 |  |  |  |  | =head2 Informational predicates
1314 |  |  |  |  |
1315 |  |  |  |  | These are a few predicate methods for asking information about the
1316 |  |  |  |  | class itself.
1317 |  |  |  |  |
1318 |  |  |  |  | =over 4
1319 |  |  |  |  |
1320 |  |  |  |  | =item B<< $metaclass->is_anon_class >>
1321 |  |  |  |  |
1322 |  |  |  |  | This returns true if the class was created by calling C<<
1323 |  |  |  |  | Class::MOP::Class->create_anon_class >>.
1324 |  |  |  |  |
1325 |  |  |  |  | =item B<< $metaclass->is_mutable >>
1326 |  |  |  |  |
1327 |  |  |  |  | This returns true if the class is still mutable.
1328 |  |  |  |  |
1329 |  |  |  |  | =item B<< $metaclass->is_immutable >>
1330 |  |  |  |  |
1331 |  |  |  |  | This returns true if the class has been made immutable.
1332 |  |  |  |  |
1333 |  |  |  |  | =item B<< $metaclass->is_pristine >>
1334 |  |  |  |  |
1335 |  |  |  |  | A class is I<not> pristine if it has non-inherited attributes or if it
1336 |  |  |  |  | has any generated methods.
1337 |  |  |  |  |
1338 |  |  |  |  | =back
1339 |  |  |  |  |
1340 |  |  |  |  | =head2 Inheritance Relationships
1341 |  |  |  |  |
1342 |  |  |  |  | =over 4
1343 |  |  |  |  |
1344 |  |  |  |  | =item B<< $metaclass->superclasses(@superclasses) >>
1345 |  |  |  |  |
1346 |  |  |  |  | This is a read-write accessor which represents the superclass
1347 |  |  |  |  | relationships of the metaclass's class.
1348 |  |  |  |  |
1349 |  |  |  |  | This is basically sugar around getting and setting C<@ISA>.
1350 |  |  |  |  |
1351 |  |  |  |  | =item B<< $metaclass->class_precedence_list >>
1352 |  |  |  |  |
1353 |  |  |  |  | This returns a list of all of the class's ancestor classes. The
1354 |  |  |  |  | classes are returned in method dispatch order.
1355 |  |  |  |  |
1356 |  |  |  |  | =item B<< $metaclass->linearized_isa >>
1357 |  |  |  |  |
1358 |  |  |  |  | This returns a list based on C<class_precedence_list> but with all
1359 |  |  |  |  | duplicates removed.
1360 |  |  |  |  |
1361 |  |  |  |  | =item B<< $metaclass->subclasses >>
1362 |  |  |  |  |
1363 |  |  |  |  | This returns a list of all subclasses for this class, even indirect
1364 |  |  |  |  | subclasses.
1365 |  |  |  |  |
1366 |  |  |  |  | =item B<< $metaclass->direct_subclasses >>
1367 |  |  |  |  |
1368 |  |  |  |  | This returns a list of immediate subclasses for this class, which does not
1369 |  |  |  |  | include indirect subclasses.
1370 |  |  |  |  |
1371 |  |  |  |  | =back
1372 |  |  |  |  |
1373 |  |  |  |  | =head2 Method introspection
1374 |  |  |  |  |
1375 |  |  |  |  | See L<Class::MOP::Package/Method introspection and creation> for
1376 |  |  |  |  | methods that operate only on the current class. Class::MOP::Class adds
1377 |  |  |  |  | introspection capabilities that take inheritance into account.
1378 |  |  |  |  |
1379 |  |  |  |  | =over 4
1380 |  |  |  |  |
1381 |  |  |  |  | =item B<< $metaclass->get_all_methods >>
1382 |  |  |  |  |
1383 |  |  |  |  | This will traverse the inheritance hierarchy and return a list of all
1384 |  |  |  |  | the L<Class::MOP::Method> objects for this class and its parents.
1385 |  |  |  |  |
1386 |  |  |  |  | =item B<< $metaclass->find_method_by_name($method_name) >>
1387 |  |  |  |  |
1388 |  |  |  |  | This will return a L<Class::MOP::Method> for the specified
1389 |  |  |  |  | C<$method_name>. If the class does not have the specified method, it
1390 |  |  |  |  | returns C<undef>
1391 |  |  |  |  |
1392 |  |  |  |  | Unlike C<get_method>, this method I<will> look for the named method in
1393 |  |  |  |  | superclasses.
1394 |  |  |  |  |
1395 |  |  |  |  | =item B<< $metaclass->get_all_method_names >>
1396 |  |  |  |  |
1397 |  |  |  |  | This will return a list of method I<names> for all of this class's
1398 |  |  |  |  | methods, including inherited methods.
1399 |  |  |  |  |
1400 |  |  |  |  | =item B<< $metaclass->find_all_methods_by_name($method_name) >>
1401 |  |  |  |  |
1402 |  |  |  |  | This method looks for the named method in the class and all of its
1403 |  |  |  |  | parents. It returns every matching method it finds in the inheritance
1404 |  |  |  |  | tree, so it returns a list of methods.
1405 |  |  |  |  |
1406 |  |  |  |  | Each method is returned as a hash reference with three keys. The keys
1407 |  |  |  |  | are C<name>, C<class>, and C<code>. The C<code> key has a
1408 |  |  |  |  | L<Class::MOP::Method> object as its value.
1409 |  |  |  |  |
1410 |  |  |  |  | The list of methods is distinct.
1411 |  |  |  |  |
1412 |  |  |  |  | =item B<< $metaclass->find_next_method_by_name($method_name) >>
1413 |  |  |  |  |
1414 |  |  |  |  | This method returns the first method in any superclass matching the
1415 |  |  |  |  | given name. It is effectively the method that C<SUPER::$method_name>
1416 |  |  |  |  | would dispatch to.
1417 |  |  |  |  |
1418 |  |  |  |  | =back
1419 |  |  |  |  |
1420 |  |  |  |  | =head2 Attribute introspection and creation
1421 |  |  |  |  |
1422 |  |  |  |  | Because Perl 5 does not have a core concept of attributes in classes,
1423 |  |  |  |  | we can only return information about attributes which have been added
1424 |  |  |  |  | via this class's methods. We cannot discover information about
1425 |  |  |  |  | attributes which are defined in terms of "regular" Perl 5 methods.
1426 |  |  |  |  |
1427 |  |  |  |  | =over 4
1428 |  |  |  |  |
1429 |  |  |  |  | =item B<< $metaclass->get_attribute($attribute_name) >>
1430 |  |  |  |  |
1431 |  |  |  |  | This will return a L<Class::MOP::Attribute> for the specified
1432 |  |  |  |  | C<$attribute_name>. If the class does not have the specified
1433 |  |  |  |  | attribute, it returns C<undef>.
1434 |  |  |  |  |
1435 |  |  |  |  | NOTE that get_attribute does not search superclasses, for that you
1436 |  |  |  |  | need to use C<find_attribute_by_name>.
1437 |  |  |  |  |
1438 |  |  |  |  | =item B<< $metaclass->has_attribute($attribute_name) >>
1439 |  |  |  |  |
1440 |  |  |  |  | Returns a boolean indicating whether or not the class defines the
1441 |  |  |  |  | named attribute. It does not include attributes inherited from parent
1442 |  |  |  |  | classes.
1443 |  |  |  |  |
1444 |  |  |  |  | =item B<< $metaclass->get_attribute_list >>
1445 |  |  |  |  |
1446 |  |  |  |  | This will return a list of attributes I<names> for all attributes
1447 |  |  |  |  | defined in this class.
1448 |  |  |  |  |
1449 |  |  |  |  | =item B<< $metaclass->get_all_attributes >>
1450 |  |  |  |  |
1451 |  |  |  |  | This will traverse the inheritance hierarchy and return a list of all
1452 |  |  |  |  | the L<Class::MOP::Attribute> objects for this class and its parents.
1453 |  |  |  |  |
1454 |  |  |  |  | =item B<< $metaclass->find_attribute_by_name($attribute_name) >>
1455 |  |  |  |  |
1456 |  |  |  |  | This will return a L<Class::MOP::Attribute> for the specified
1457 |  |  |  |  | C<$attribute_name>. If the class does not have the specified
1458 |  |  |  |  | attribute, it returns C<undef>.
1459 |  |  |  |  |
1460 |  |  |  |  | Unlike C<get_attribute>, this attribute I<will> look for the named
1461 |  |  |  |  | attribute in superclasses.
1462 |  |  |  |  |
1463 |  |  |  |  | =item B<< $metaclass->add_attribute(...) >>
1464 |  |  |  |  |
1465 |  |  |  |  | This method accepts either an existing L<Class::MOP::Attribute>
1466 |  |  |  |  | object or parameters suitable for passing to that class's C<new>
1467 |  |  |  |  | method.
1468 |  |  |  |  |
1469 |  |  |  |  | The attribute provided will be added to the class.
1470 |  |  |  |  |
1471 |  |  |  |  | Any accessor methods defined by the attribute will be added to the
1472 |  |  |  |  | class when the attribute is added.
1473 |  |  |  |  |
1474 |  |  |  |  | If an attribute of the same name already exists, the old attribute
1475 |  |  |  |  | will be removed first.
1476 |  |  |  |  |
1477 |  |  |  |  | =item B<< $metaclass->remove_attribute($attribute_name) >>
1478 |  |  |  |  |
1479 |  |  |  |  | This will remove the named attribute from the class, and
1480 |  |  |  |  | L<Class::MOP::Attribute> object.
1481 |  |  |  |  |
1482 |  |  |  |  | Removing an attribute also removes any accessor methods defined by the
1483 |  |  |  |  | attribute.
1484 |  |  |  |  |
1485 |  |  |  |  | However, note that removing an attribute will only affect I<future>
1486 |  |  |  |  | object instances created for this class, not existing instances.
1487 |  |  |  |  |
1488 |  |  |  |  | =item B<< $metaclass->attribute_metaclass >>
1489 |  |  |  |  |
1490 |  |  |  |  | Returns the class name of the attribute metaclass for this class. By
1491 |  |  |  |  | default, this is L<Class::MOP::Attribute>.
1492 |  |  |  |  |
1493 |  |  |  |  | =back
1494 |  |  |  |  |
1495 |  |  |  |  | =head2 Class Immutability
1496 |  |  |  |  |
1497 |  |  |  |  | Making a class immutable "freezes" the class definition. You can no
1498 |  |  |  |  | longer call methods which alter the class, such as adding or removing
1499 |  |  |  |  | methods or attributes.
1500 |  |  |  |  |
1501 |  |  |  |  | Making a class immutable lets us optimize the class by inlining some
1502 |  |  |  |  | methods, and also allows us to optimize some methods on the metaclass
1503 |  |  |  |  | object itself.
1504 |  |  |  |  |
1505 |  |  |  |  | After immutabilization, the metaclass object will cache most informational
1506 |  |  |  |  | methods that returns information about methods or attributes. Methods which
1507 |  |  |  |  | would alter the class, such as C<add_attribute> and C<add_method>, will
1508 |  |  |  |  | throw an error on an immutable metaclass object.
1509 |  |  |  |  |
1510 |  |  |  |  | The immutabilization system in L<Moose> takes much greater advantage
1511 |  |  |  |  | of the inlining features than Class::MOP itself does.
1512 |  |  |  |  |
1513 |  |  |  |  | =over 4
1514 |  |  |  |  |
1515 |  |  |  |  | =item B<< $metaclass->make_immutable(%options) >>
1516 |  |  |  |  |
1517 |  |  |  |  | This method will create an immutable transformer and use it to make
1518 |  |  |  |  | the class and its metaclass object immutable.
1519 |  |  |  |  |
1520 |  |  |  |  | This 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 |  |  |  |  |
1530 |  |  |  |  | These are all booleans indicating whether the specified method(s)
1531 |  |  |  |  | should be inlined.
1532 |  |  |  |  |
1533 |  |  |  |  | By default, accessors and the constructor are inlined, but not the
1534 |  |  |  |  | destructor.
1535 |  |  |  |  |
1536 |  |  |  |  | =item * immutable_trait
1537 |  |  |  |  |
1538 |  |  |  |  | The name of a class which will be used as a parent class for the
1539 |  |  |  |  | metaclass object being made immutable. This "trait" implements the
1540 |  |  |  |  | post-immutability functionality of the metaclass (but not the
1541 |  |  |  |  | transformation itself).
1542 |  |  |  |  |
1543 |  |  |  |  | This defaults to L<Class::MOP::Class::Immutable::Trait>.
1544 |  |  |  |  |
1545 |  |  |  |  | =item * constructor_name
1546 |  |  |  |  |
1547 |  |  |  |  | This is the constructor method name. This defaults to "new".
1548 |  |  |  |  |
1549 |  |  |  |  | =item * constructor_class
1550 |  |  |  |  |
1551 |  |  |  |  | The name of the method metaclass for constructors. It will be used to
1552 |  |  |  |  | generate the inlined constructor. This defaults to
1553 |  |  |  |  | "Class::MOP::Method::Constructor".
1554 |  |  |  |  |
1555 |  |  |  |  | =item * replace_constructor
1556 |  |  |  |  |
1557 |  |  |  |  | This is a boolean indicating whether an existing constructor should be
1558 |  |  |  |  | replaced when inlining a constructor. This defaults to false.
1559 |  |  |  |  |
1560 |  |  |  |  | =item * destructor_class
1561 |  |  |  |  |
1562 |  |  |  |  | The name of the method metaclass for destructors. It will be used to
1563 |  |  |  |  | generate the inlined destructor. This defaults to
1564 |  |  |  |  | "Class::MOP::Method::Denstructor".
1565 |  |  |  |  |
1566 |  |  |  |  | =item * replace_destructor
1567 |  |  |  |  |
1568 |  |  |  |  | This is a boolean indicating whether an existing destructor should be
1569 |  |  |  |  | replaced when inlining a destructor. This defaults to false.
1570 |  |  |  |  |
1571 |  |  |  |  | =back
1572 |  |  |  |  |
1573 |  |  |  |  | =item B<< $metaclass->immutable_options >>
1574 |  |  |  |  |
1575 |  |  |  |  | Returns a hash of the options used when making the class immutable, including
1576 |  |  |  |  | both 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
1578 |  |  |  |  | a class mutable and then restore immutability as it was before.
1579 |  |  |  |  |
1580 |  |  |  |  | =item B<< $metaclass->make_mutable >>
1581 |  |  |  |  |
1582 |  |  |  |  | Calling this method reverse the immutabilization transformation.
1583 |  |  |  |  |
1584 |  |  |  |  | =back
1585 |  |  |  |  |
1586 |  |  |  |  | =head2 Method Modifiers
1587 |  |  |  |  |
1588 |  |  |  |  | Method modifiers are hooks which allow a method to be wrapped with
1589 |  |  |  |  | I<before>, I<after> and I<around> method modifiers. Every time a
1590 |  |  |  |  | method is called, its modifiers are also called.
1591 |  |  |  |  |
1592 |  |  |  |  | A class can modify its own methods, as well as methods defined in
1593 |  |  |  |  | parent classes.
1594 |  |  |  |  |
1595 |  |  |  |  | =head3 How method modifiers work?
1596 |  |  |  |  |
1597 |  |  |  |  | Method modifiers work by wrapping the original method and then
1598 |  |  |  |  | replacing it in the class's symbol table. The wrappers will handle
1599 |  |  |  |  | calling all the modifiers in the appropriate order and preserving the
1600 |  |  |  |  | calling context for the original method.
1601 |  |  |  |  |
1602 |  |  |  |  | The return values of C<before> and C<after> modifiers are
1603 |  |  |  |  | ignored. This is because their purpose is B<not> to filter the input
1604 |  |  |  |  | and output of the primary method (this is done with an I<around>
1605 |  |  |  |  | modifier).
1606 |  |  |  |  |
1607 |  |  |  |  | This may seem like an odd restriction to some, but doing this allows
1608 |  |  |  |  | for simple code to be added at the beginning or end of a method call
1609 |  |  |  |  | without altering the function of the wrapped method or placing any
1610 |  |  |  |  | extra responsibility on the code of the modifier.
1611 |  |  |  |  |
1612 |  |  |  |  | Of course if you have more complex needs, you can use the C<around>
1613 |  |  |  |  | modifier which allows you to change both the parameters passed to the
1614 |  |  |  |  | wrapped method, as well as its return value.
1615 |  |  |  |  |
1616 |  |  |  |  | Before and around modifiers are called in last-defined-first-called
1617 |  |  |  |  | order, while after modifiers are called in first-defined-first-called
1618 |  |  |  |  | order. 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 |  |  |  |  |
1632 |  |  |  |  | Of course there is a performance cost associated with method
1633 |  |  |  |  | modifiers, but we have made every effort to make that cost directly
1634 |  |  |  |  | proportional to the number of modifier features you use.
1635 |  |  |  |  |
1636 |  |  |  |  | The wrapping method does its best to B<only> do as much work as it
1637 |  |  |  |  | absolutely needs to. In order to do this we have moved some of the
1638 |  |  |  |  | performance costs to set-up time, where they are easier to amortize.
1639 |  |  |  |  |
1640 |  |  |  |  | All 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 |  |  |  |  |
1648 |  |  |  |  | These numbers may seem daunting, but you must remember, every feature
1649 |  |  |  |  | comes with some cost. To put things in perspective, just doing a
1650 |  |  |  |  | simple C<AUTOLOAD> which does nothing but extract the name of the
1651 |  |  |  |  | method called and return it costs about 400% over a normal method
1652 |  |  |  |  | call.
1653 |  |  |  |  |
1654 |  |  |  |  | =over 4
1655 |  |  |  |  |
1656 |  |  |  |  | =item B<< $metaclass->add_before_method_modifier($method_name, $code) >>
1657 |  |  |  |  |
1658 |  |  |  |  | This wraps the specified method with the supplied subroutine
1659 |  |  |  |  | reference. The modifier will be called as a method itself, and will
1660 |  |  |  |  | receive the same arguments as are passed to the method.
1661 |  |  |  |  |
1662 |  |  |  |  | When the modifier exits, the wrapped method will be called.
1663 |  |  |  |  |
1664 |  |  |  |  | The return value of the modifier will be ignored.
1665 |  |  |  |  |
1666 |  |  |  |  | =item B<< $metaclass->add_after_method_modifier($method_name, $code) >>
1667 |  |  |  |  |
1668 |  |  |  |  | This wraps the specified method with the supplied subroutine
1669 |  |  |  |  | reference. The modifier will be called as a method itself, and will
1670 |  |  |  |  | receive the same arguments as are passed to the method.
1671 |  |  |  |  |
1672 |  |  |  |  | When the wrapped methods exits, the modifier will be called.
1673 |  |  |  |  |
1674 |  |  |  |  | The return value of the modifier will be ignored.
1675 |  |  |  |  |
1676 |  |  |  |  | =item B<< $metaclass->add_around_method_modifier($method_name, $code) >>
1677 |  |  |  |  |
1678 |  |  |  |  | This wraps the specified method with the supplied subroutine
1679 |  |  |  |  | reference.
1680 |  |  |  |  |
1681 |  |  |  |  | The first argument passed to the modifier will be a subroutine
1682 |  |  |  |  | reference to the wrapped method. The second argument is the object,
1683 |  |  |  |  | and after that come any arguments passed when the method is called.
1684 |  |  |  |  |
1685 |  |  |  |  | The around modifier can choose to call the original method, as well as
1686 |  |  |  |  | what arguments to pass if it does so.
1687 |  |  |  |  |
1688 |  |  |  |  | The 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 |  |  |  |  |
1698 |  |  |  |  | This will return a L<Class::MOP::Class> instance for this class.
1699 |  |  |  |  |
1700 |  |  |  |  | It should also be noted that L<Class::MOP> will actually bootstrap
1701 |  |  |  |  | this module by installing a number of attribute meta-objects into its
1702 |  |  |  |  | metaclass.
1703 |  |  |  |  |
1704 |  |  |  |  | =back
1705 |  |  |  |  |
1706 |  |  |  |  | =head1 AUTHORS
1707 |  |  |  |  |
1708 |  |  |  |  | Stevan Little E<lt>stevan@iinteractive.comE<gt>
1709 |  |  |  |  |
1710 |  |  |  |  | =head1 COPYRIGHT AND LICENSE
1711 |  |  |  |  |
1712 |  |  |  |  | Copyright 2006-2010 by Infinity Interactive, Inc.
1713 |  |  |  |  |
1714 |  |  |  |  | L<http://www.iinteractive.com>
1715 |  |  |  |  |
1716 |  |  |  |  | This library is free software; you can redistribute it and/or modify
1717 |  |  |  |  | it 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