Profile of Moose/Util.pm

← Index
NYTProf Performance Profile «line view»
For script/ponapi
Run on Wed Feb 10 15:51:26 2016
Reported on Thu Feb 11 09:43:10 2016

Filename | /usr/local/lib/perl/5.18.2/Moose/Util.pm
Statements | Executed 3694966 statements in 20.8s

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1230932 | 7 | 1 | 13.0s | 110s | Moose::Util::::does_roleMoose::Util::does_role
42 | 1 | 1 | 2.14ms | 606ms | Moose::Util::::_apply_all_rolesMoose::Util::_apply_all_roles (recurses: max depth 3, inclusive time 151ms)
62 | 2 | 2 | 527µs | 527µs | Moose::Util::::_caller_infoMoose::Util::_caller_info
121 | 3 | 3 | 412µs | 585ms | Moose::Util::::_load_user_classMoose::Util::_load_user_class (recurses: max depth 1, inclusive time 7.22ms)
64 | 1 | 1 | 374µs | 24.0ms | Moose::Util::::resolve_metaclass_aliasMoose::Util::resolve_metaclass_alias
96 | 2 | 1 | 253µs | 563µs | Moose::Util::::find_metaMoose::Util::find_meta
64 | 2 | 1 | 202µs | 24.2ms | Moose::Util::::resolve_metatrait_aliasMoose::Util::resolve_metatrait_alias
42 | 3 | 3 | 185µs | 606ms | Moose::Util::::apply_all_rolesMoose::Util::apply_all_roles (recurses: max depth 3, inclusive time 151ms)
9 | 1 | 1 | 81µs | 212µs | Moose::Util::::add_method_modifierMoose::Util::add_method_modifier
50 | 1 | 1 | 52µs | 52µs | Moose::Util::::__ANON__[:136]Moose::Util::__ANON__[:136]
4 | 1 | 1 | 16µs | 16µs | Moose::Util::::_build_alias_package_nameMoose::Util::_build_alias_package_name
1 | 1 | 1 | 12µs | 45µs | Moose::Util::::BEGIN@12Moose::Util::BEGIN@12
1 | 1 | 1 | 10µs | 40µs | Moose::Util::::BEGIN@7Moose::Util::BEGIN@7
1 | 1 | 1 | 9µs | 134µs | Moose::Util::::BEGIN@10Moose::Util::BEGIN@10
1 | 1 | 1 | 8µs | 12µs | Moose::Util::::BEGIN@8Moose::Util::BEGIN@8
1 | 1 | 1 | 8µs | 16µs | Moose::Util::::BEGIN@4Moose::Util::BEGIN@4
1 | 1 | 1 | 6µs | 10µs | Moose::Util::::BEGIN@5Moose::Util::BEGIN@5
1 | 1 | 1 | 6µs | 31µs | Moose::Util::::BEGIN@14Moose::Util::BEGIN@14
1 | 1 | 1 | 6µs | 24µs | Moose::Util::::BEGIN@9Moose::Util::BEGIN@9
1 | 1 | 1 | 5µs | 23µs | Moose::Util::::BEGIN@11Moose::Util::BEGIN@11
1 | 1 | 1 | 3µs | 3µs | Moose::Util::::BEGIN@13Moose::Util::BEGIN@13
0 | 0 | 0 | 0s | 0s | Moose::Util::::_STRINGLIKE0Moose::Util::_STRINGLIKE0
0 | 0 | 0 | 0s | 0s | Moose::Util::::__ANON__[:109]Moose::Util::__ANON__[:109]
0 | 0 | 0 | 0s | 0s | Moose::Util::::__ANON__[:327]Moose::Util::__ANON__[:327]
0 | 0 | 0 | 0s | 0s | Moose::Util::::__ANON__[:411]Moose::Util::__ANON__[:411]
0 | 0 | 0 | 0s | 0s | Moose::Util::::__ANON__[:430]Moose::Util::__ANON__[:430]
0 | 0 | 0 | 0s | 0s | Moose::Util::::__ANON__[:449]Moose::Util::__ANON__[:449]
0 | 0 | 0 | 0s | 0s | Moose::Util::::__ANON__[:499]Moose::Util::__ANON__[:499]
0 | 0 | 0 | 0s | 0s | Moose::Util::::__ANON__[:501]Moose::Util::__ANON__[:501]
0 | 0 | 0 | 0s | 0s | Moose::Util::::__ANON__[:503]Moose::Util::__ANON__[:503]
0 | 0 | 0 | 0s | 0s | Moose::Util::::__ANON__[:515]Moose::Util::__ANON__[:515]
0 | 0 | 0 | 0s | 0s | Moose::Util::::__ANON__[:69]Moose::Util::__ANON__[:69]
0 | 0 | 0 | 0s | 0s | Moose::Util::::_classes_differ_by_roles_onlyMoose::Util::_classes_differ_by_roles_only
0 | 0 | 0 | 0s | 0s | Moose::Util::::_create_aliasMoose::Util::_create_alias
0 | 0 | 0 | 0s | 0s | Moose::Util::::_english_listMoose::Util::_english_list
0 | 0 | 0 | 0s | 0s | Moose::Util::::_english_list_andMoose::Util::_english_list_and
0 | 0 | 0 | 0s | 0s | Moose::Util::::_english_list_orMoose::Util::_english_list_or
0 | 0 | 0 | 0s | 0s | Moose::Util::::_find_common_baseMoose::Util::_find_common_base
0 | 0 | 0 | 0s | 0s | Moose::Util::::_get_ancestors_untilMoose::Util::_get_ancestors_until
0 | 0 | 0 | 0s | 0s | Moose::Util::::_is_package_loadedMoose::Util::_is_package_loaded
0 | 0 | 0 | 0s | 0s | Moose::Util::::_is_role_only_subclassMoose::Util::_is_role_only_subclass
0 | 0 | 0 | 0s | 0s | Moose::Util::::_reconcile_roles_for_metaclassMoose::Util::_reconcile_roles_for_metaclass
0 | 0 | 0 | 0s | 0s | Moose::Util::::_role_differencesMoose::Util::_role_differences
0 | 0 | 0 | 0s | 0s | Moose::Util::::english_listMoose::Util::english_list
0 | 0 | 0 | 0s | 0s | Moose::Util::::ensure_all_rolesMoose::Util::ensure_all_roles
0 | 0 | 0 | 0s | 0s | Moose::Util::::get_all_attribute_valuesMoose::Util::get_all_attribute_values
0 | 0 | 0 | 0s | 0s | Moose::Util::::get_all_init_argsMoose::Util::get_all_init_args
0 | 0 | 0 | 0s | 0s | Moose::Util::::is_roleMoose::Util::is_role
0 | 0 | 0 | 0s | 0s | Moose::Util::::meta_attribute_aliasMoose::Util::meta_attribute_alias
0 | 0 | 0 | 0s | 0s | Moose::Util::::meta_class_aliasMoose::Util::meta_class_alias
0 | 0 | 0 | 0s | 0s | Moose::Util::::search_class_by_roleMoose::Util::search_class_by_role
0 | 0 | 0 | 0s | 0s | Moose::Util::::throw_exceptionMoose::Util::throw_exception
0 | 0 | 0 | 0s | 0s | Moose::Util::::with_traitsMoose::Util::with_traits

Call graph for these subroutines as a Graphviz dot language file.

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 |  |  |  |  | package Moose::Util;
2 | 1 | 700ns |  |  | our $VERSION = '2.1604';
3 |  |  |  |  |
4 | 2 | 20µs | 2 | 24µs | # spent 16µs (8+8) within Moose::Util::BEGIN@4 which was called: # once (8µs+8µs) by Moose::Util::MetaRole::BEGIN@10 at line 4 use strict; # spent 16µs making 1 call to Moose::Util::BEGIN@4 # spent 8µs making 1 call to strict::import
5 | 2 | 23µs | 2 | 13µs | # spent 10µs (6+3) within Moose::Util::BEGIN@5 which was called: # once (6µs+3µs) by Moose::Util::MetaRole::BEGIN@10 at line 5 use warnings; # spent 10µs making 1 call to Moose::Util::BEGIN@5 # spent 3µs making 1 call to warnings::import
6 |  |  |  |  |
7 | 3 | 32µs | 3 | 69µs | # spent 40µs (10+30) within Moose::Util::BEGIN@7 which was called: # once (10µs+30µs) by Moose::Util::MetaRole::BEGIN@10 at line 7 use Module::Runtime 0.014 'use_package_optimistically', 'use_module', 'module_notional_filename'; # spent 40µs making 1 call to Moose::Util::BEGIN@7 # spent 21µs making 1 call to Module::Runtime::import # spent 9µs making 1 call to UNIVERSAL::VERSION
8 | 2 | 20µs | 2 | 15µs | # spent 12µs (8+4) within Moose::Util::BEGIN@8 which was called: # once (8µs+4µs) by Moose::Util::MetaRole::BEGIN@10 at line 8 use Data::OptList; # spent 12µs making 1 call to Moose::Util::BEGIN@8 # spent 4µs making 1 call to Sub::Install::__ANON__[Sub/Install.pm:270]
9 | 2 | 19µs | 2 | 42µs | # spent 24µs (6+18) within Moose::Util::BEGIN@9 which was called: # once (6µs+18µs) by Moose::Util::MetaRole::BEGIN@10 at line 9 use Params::Util qw( _STRING ); # spent 24µs making 1 call to Moose::Util::BEGIN@9 # spent 18µs making 1 call to Exporter::import
10 | 2 | 26µs | 2 | 259µs | # spent 134µs (9+125) within Moose::Util::BEGIN@10 which was called: # once (9µs+125µs) by Moose::Util::MetaRole::BEGIN@10 at line 10 use Sub::Exporter; # spent 134µs making 1 call to Moose::Util::BEGIN@10 # spent 125µs making 1 call to Sub::Exporter::__ANON__[Sub/Exporter.pm:337]
11 | 2 | 24µs | 2 | 41µs | # spent 23µs (5+18) within Moose::Util::BEGIN@11 which was called: # once (5µs+18µs) by Moose::Util::MetaRole::BEGIN@10 at line 11 use Scalar::Util 'blessed'; # spent 23µs making 1 call to Moose::Util::BEGIN@11 # spent 18µs making 1 call to Exporter::import
12 | 3 | 31µs | 3 | 57µs | # spent 45µs (12+33) within Moose::Util::BEGIN@12 which was called: # once (12µs+33µs) by Moose::Util::MetaRole::BEGIN@10 at line 12 use List::Util 1.33 qw(first any all); # spent 45µs making 1 call to Moose::Util::BEGIN@12 # spent 7µs making 1 call to UNIVERSAL::VERSION # spent 5µs making 1 call to List::Util::import
13 | 2 | 15µs | 1 | 3µs | # spent 3µs within Moose::Util::BEGIN@13 which was called: # once (3µs+0s) by Moose::Util::MetaRole::BEGIN@10 at line 13 use overload (); # spent 3µs making 1 call to Moose::Util::BEGIN@13
14 | 2 | 2.00ms | 2 | 57µs | # spent 31µs (6+26) within Moose::Util::BEGIN@14 which was called: # once (6µs+26µs) by Moose::Util::MetaRole::BEGIN@10 at line 14 use Try::Tiny; # spent 31µs making 1 call to Moose::Util::BEGIN@14 # spent 26µs making 1 call to Exporter::import
15 |  |  |  |  |
16 |  |  |  |  |
17 | 1 | 2µs |  |  | my @exports = qw[
18 |  |  |  |  | find_meta
19 |  |  |  |  | is_role
20 |  |  |  |  | does_role
21 |  |  |  |  | search_class_by_role
22 |  |  |  |  | ensure_all_roles
23 |  |  |  |  | apply_all_roles
24 |  |  |  |  | with_traits
25 |  |  |  |  | get_all_init_args
26 |  |  |  |  | get_all_attribute_values
27 |  |  |  |  | resolve_metatrait_alias
28 |  |  |  |  | resolve_metaclass_alias
29 |  |  |  |  | add_method_modifier
30 |  |  |  |  | english_list
31 |  |  |  |  | meta_attribute_alias
32 |  |  |  |  | meta_class_alias
33 |  |  |  |  | throw_exception
34 |  |  |  |  | ];
35 |  |  |  |  |
36 | 1 | 5µs | 1 | 304µs | Sub::Exporter::setup_exporter({ # spent 304µs making 1 call to Sub::Exporter::setup_exporter
37 |  |  |  |  | exports => \@exports,
38 |  |  |  |  | groups => { all => \@exports }
39 |  |  |  |  | });
40 |  |  |  |  |
41 |  |  |  |  | # Things that need to ->import from Moose::Util
42 |  |  |  |  | # should be loaded after Moose::Util defines ->import
43 | 1 | 1µs |  |  | require Class::MOP;
44 |  |  |  |  |
45 |  |  |  |  | sub throw_exception {
46 |  |  |  |  | my ($class_name, @args_to_exception) = @_;
47 |  |  |  |  | my $class = "Moose::Exception::$class_name";
48 |  |  |  |  | _load_user_class( $class );
49 |  |  |  |  | die $class->new( @args_to_exception );
50 |  |  |  |  | }
51 |  |  |  |  |
52 |  |  |  |  | ## some utils for the utils ...
53 |  |  |  |  |
54 | 96 | 217µs | 96 | 310µs | # spent 563µs (253+310) within Moose::Util::find_meta which was called 96 times, avg 6µs/call: # 92 times (244µs+295µs) by Moose::Util::_apply_all_roles at line 148, avg 6µs/call # 4 times (9µs+15µs) by Moose::Util::resolve_metaclass_alias at line 240, avg 6µs/call sub find_meta { Class::MOP::class_of(@_) } # spent 310µs making 96 calls to Class::MOP::class_of, avg 3µs/call
55 |  |  |  |  |
56 |  |  |  |  | ## the functions ...
57 |  |  |  |  |
58 |  |  |  |  | sub is_role {
59 |  |  |  |  | my $package_or_obj = shift;
60 |  |  |  |  |
61 |  |  |  |  | my $meta = find_meta($package_or_obj);
62 |  |  |  |  | return if not $meta;
63 |  |  |  |  | return $meta->isa('Moose::Meta::Role');
64 |  |  |  |  | }
65 |  |  |  |  |
66 |  |  |  |  | # spent 110s (13.0+97.5) within Moose::Util::does_role which was called 1230932 times, avg 90µs/call: # 529024 times (4.93s+38.0s) by PONAPI::Builder::Links::new at line 48 of (eval 45)[Eval/Closure.pm:144], avg 81µs/call # 270247 times (3.14s+22.9s) by PONAPI::Builder::Resource::new at line 60 of (eval 45)[Eval/Closure.pm:144], avg 97µs/call # 172883 times (1.48s+10.8s) by PONAPI::Builder::Resource::Identifier::new at line 57 of (eval 45)[Eval/Closure.pm:144], avg 71µs/call # 158776 times (1.67s+12.6s) by PONAPI::Builder::Relationship::new at line 66 of (eval 45)[Eval/Closure.pm:144], avg 90µs/call # 50245 times (874ms+6.69s) by PONAPI::DAO::Request::RetrieveAll::new at line 111 of (eval 45)[Eval/Closure.pm:144], avg 150µs/call # 49756 times (855ms+6.49s) by PONAPI::DAO::Request::Retrieve::new at line 118 of (eval 45)[Eval/Closure.pm:144], avg 148µs/call # once (20µs+571µs) by PONAPI::DAO::new at line 56 of (eval 45)[Eval/Closure.pm:144] sub does_role {
67 | 1230932 | 601ms |  |  | my ($class_or_obj, $role) = @_;
68 |  |  |  |  |
69 | 2461864 | 20.2s | 3692796 | 68.3s | if (try { $class_or_obj->isa('Moose::Object') }) { # spent 67.0s making 1230932 calls to Moose::Object::does, avg 54µs/call # spent 1.30s making 1230932 calls to UNIVERSAL::isa, avg 1µs/call # spent 30.5s making 1230932 calls to Try::Tiny::try, avg 25µs/call, recursion: max depth 1, sum of overlapping time 30.5s
70 |  |  |  |  | return $class_or_obj->does($role);
71 |  |  |  |  | }
72 |  |  |  |  |
73 |  |  |  |  | my $meta = find_meta($class_or_obj);
74 |  |  |  |  |
75 |  |  |  |  | return unless defined $meta;
76 |  |  |  |  | return unless $meta->can('does_role');
77 |  |  |  |  | return 1 if $meta->does_role($role);
78 |  |  |  |  | return;
79 |  |  |  |  | }
80 |  |  |  |  |
81 |  |  |  |  | sub search_class_by_role {
82 |  |  |  |  | my ($class_or_obj, $role) = @_;
83 |  |  |  |  |
84 |  |  |  |  | my $meta = find_meta($class_or_obj);
85 |  |  |  |  |
86 |  |  |  |  | return unless defined $meta;
87 |  |  |  |  |
88 |  |  |  |  | my $role_name = blessed $role ? $role->name : $role;
89 |  |  |  |  |
90 |  |  |  |  | foreach my $class ($meta->class_precedence_list) {
91 |  |  |  |  |
92 |  |  |  |  | my $_meta = find_meta($class);
93 |  |  |  |  |
94 |  |  |  |  | next unless defined $_meta;
95 |  |  |  |  |
96 |  |  |  |  | foreach my $role (@{ $_meta->roles || [] }) {
97 |  |  |  |  | return $class if $role->name eq $role_name;
98 |  |  |  |  | }
99 |  |  |  |  | }
100 |  |  |  |  |
101 |  |  |  |  | return;
102 |  |  |  |  | }
103 |  |  |  |  |
104 |  |  |  |  | # this can possibly behave in unexpected ways because the roles being composed
105 |  |  |  |  | # before being applied could differ from call to call; I'm not sure if or how
106 |  |  |  |  | # to document this possible quirk.
107 |  |  |  |  | sub ensure_all_roles {
108 |  |  |  |  | my $applicant = shift;
109 |  |  |  |  | _apply_all_roles($applicant, sub { !does_role($applicant, $_) }, @_);
110 |  |  |  |  | }
111 |  |  |  |  |
112 |  |  |  |  | # spent 606ms (185µs+605) within Moose::Util::apply_all_roles which was called 42 times, avg 14.4ms/call: # 18 times (71µs+547ms) by Moose::with at line 59 of Moose.pm, avg 30.4ms/call # 14 times (77µs+34.6ms) by Moose::Role::with at line 25 of Moose/Role.pm, avg 2.48ms/call # 10 times (37µs+23.6ms) by Moose::Meta::Class::create at line 89 of Moose/Meta/Class.pm, avg 2.36ms/call sub apply_all_roles {
113 | 42 | 26µs |  |  | my $applicant = shift;
114 | 42 | 172µs | 42 | 606ms | _apply_all_roles($applicant, undef, @_); # spent 756ms making 42 calls to Moose::Util::_apply_all_roles, avg 18.0ms/call, recursion: max depth 3, sum of overlapping time 151ms
115 |  |  |  |  | }
116 |  |  |  |  |
117 |  |  |  |  | # spent 606ms (2.14+603) within Moose::Util::_apply_all_roles which was called 42 times, avg 14.4ms/call: # 42 times (2.14ms+603ms) by Moose::Util::apply_all_roles at line 114, avg 14.4ms/call sub _apply_all_roles {
118 | 42 | 16µs |  |  | my $applicant = shift;
119 | 42 | 9µs |  |  | my $role_filter = shift;
120 |  |  |  |  |
121 | 42 | 18µs |  |  | unless (@_) {
122 |  |  |  |  | require Moose;
123 |  |  |  |  | throw_exception( MustSpecifyAtleastOneRoleToApplicant => applicant => $applicant );
124 |  |  |  |  | }
125 |  |  |  |  |
126 |  |  |  |  | # If @_ contains role meta objects, mkopt will think that they're values,
127 |  |  |  |  | # because they're references. In other words (roleobj1, roleobj2,
128 |  |  |  |  | # roleobj3) will become [ [ roleobj1, roleobj2 ], [ roleobj3, undef ] ]
129 |  |  |  |  | # -- this is no good. We'll preprocess @_ first to eliminate the potential
130 |  |  |  |  | # bug.
131 |  |  |  |  | # -- rjbs, 2011-04-08
132 |  |  |  |  | my $roles = Data::OptList::mkopt( [@_], {
133 |  |  |  |  | moniker => 'role',
134 |  |  |  |  | # spent 52µs within Moose::Util::__ANON__[/usr/local/lib/perl/5.18.2/Moose/Util.pm:136] which was called 50 times, avg 1µs/call: # 50 times (52µs+0s) by Data::OptList::mkopt at line 71 of Data/OptList.pm, avg 1µs/call name_test => sub {
135 | 50 | 111µs |  |  | ! ref $_[0] or blessed($_[0]) && $_[0]->isa('Moose::Meta::Role')
136 |  |  |  |  | }
137 | 42 | 386µs | 42 | 843µs | }); # spent 843µs making 42 calls to Data::OptList::mkopt, avg 20µs/call
138 |  |  |  |  |
139 | 42 | 9µs |  |  | my @role_metas;
140 | 42 | 63µs |  |  | foreach my $role (@$roles) {
141 | 92 | 11µs |  |  | my $meta;
142 |  |  |  |  |
143 | 92 | 242µs | 92 | 46µs | if ( blessed $role->[0] ) { # spent 46µs making 92 calls to Scalar::Util::blessed, avg 503ns/call
144 |  |  |  |  | $meta = $role->[0];
145 |  |  |  |  | }
146 |  |  |  |  | else {
147 | 92 | 127µs | 92 | 245ms | &use_module($role->[0], $role->[1] && $role->[1]{-version} ? $role->[1]{-version} : ()); # spent 284ms making 92 calls to Module::Runtime::use_module, avg 3.08ms/call, recursion: max depth 3, sum of overlapping time 38.4ms
148 | 92 | 168µs | 92 | 539µs | $meta = find_meta( $role->[0] ); # spent 539µs making 92 calls to Moose::Util::find_meta, avg 6µs/call
149 |  |  |  |  | }
150 |  |  |  |  |
151 | 92 | 260µs | 92 | 75µs | unless ($meta && $meta->isa('Moose::Meta::Role') ) { # spent 75µs making 92 calls to UNIVERSAL::isa, avg 812ns/call
152 |  |  |  |  | throw_exception( CanOnlyConsumeRole => role_name => $role->[0] );
153 |  |  |  |  | }
154 |  |  |  |  |
155 | 92 | 143µs |  |  | push @role_metas, [ $meta, $role->[1] ];
156 |  |  |  |  | }
157 |  |  |  |  |
158 | 42 | 12µs |  |  | if ( defined $role_filter ) {
159 |  |  |  |  | @role_metas = grep { local $_ = $_->[0]; $role_filter->() } @role_metas;
160 |  |  |  |  | }
161 |  |  |  |  |
162 | 42 | 17µs |  |  | return unless @role_metas;
163 |  |  |  |  |
164 | 42 | 157µs | 42 | 45µs | _load_user_class($applicant) # spent 45µs making 42 calls to Scalar::Util::blessed, avg 1µs/call
165 |  |  |  |  | unless blessed($applicant)
166 |  |  |  |  | || Class::MOP::class_of($applicant);
167 |  |  |  |  |
168 | 42 | 110µs | 42 | 24µs | my $meta = ( blessed $applicant ? $applicant : Moose::Meta::Class->initialize($applicant) ); # spent 24µs making 42 calls to Scalar::Util::blessed, avg 562ns/call
169 |  |  |  |  |
170 | 42 | 224µs |  |  | if ( scalar @role_metas == 1 ) {
171 | 23 | 12µs |  |  | my ( $role, $params ) = @{ $role_metas[0] };
172 | 23 | 53µs | 23 | 78.0ms | $role->apply( $meta, ( defined $params ? %$params : () ) ); # spent 107ms making 23 calls to Moose::Meta::Role::apply, avg 4.66ms/call, recursion: max depth 1, sum of overlapping time 29.3ms
173 |  |  |  |  | }
174 |  |  |  |  | else {
175 | 19 | 99µs | 38 | 362ms | Moose::Meta::Role->combine(@role_metas)->apply($meta); # spent 300ms making 19 calls to Moose::Meta::Role::apply, avg 15.8ms/call # spent 61.4ms making 19 calls to Moose::Meta::Role::combine, avg 3.23ms/call
176 |  |  |  |  | }
177 |  |  |  |  | }
178 |  |  |  |  |
179 |  |  |  |  | sub with_traits {
180 |  |  |  |  | my ($class, @roles) = @_;
181 |  |  |  |  | return $class unless @roles;
182 |  |  |  |  | return Moose::Meta::Class->create_anon_class(
183 |  |  |  |  | superclasses => [$class],
184 |  |  |  |  | roles => \@roles,
185 |  |  |  |  | cache => 1,
186 |  |  |  |  | )->name;
187 |  |  |  |  | }
188 |  |  |  |  |
189 |  |  |  |  | # instance deconstruction ...
190 |  |  |  |  |
191 |  |  |  |  | sub get_all_attribute_values {
192 |  |  |  |  | my ($class, $instance) = @_;
193 |  |  |  |  | return +{
194 |  |  |  |  | map { $_->name => $_->get_value($instance) }
195 |  |  |  |  | grep { $_->has_value($instance) }
196 |  |  |  |  | $class->get_all_attributes
197 |  |  |  |  | };
198 |  |  |  |  | }
199 |  |  |  |  |
200 |  |  |  |  | sub get_all_init_args {
201 |  |  |  |  | my ($class, $instance) = @_;
202 |  |  |  |  | return +{
203 |  |  |  |  | map { $_->init_arg => $_->get_value($instance) }
204 |  |  |  |  | grep { $_->has_value($instance) }
205 |  |  |  |  | grep { defined($_->init_arg) }
206 |  |  |  |  | $class->get_all_attributes
207 |  |  |  |  | };
208 |  |  |  |  | }
209 |  |  |  |  |
210 |  |  |  |  | # spent 24.2ms (202µs+24.0) within Moose::Util::resolve_metatrait_alias which was called 64 times, avg 377µs/call: # 32 times (140µs+23.4ms) by Moose::Meta::Attribute::interpolate_class at line 129 of Moose/Meta/Attribute.pm, avg 737µs/call # 32 times (62µs+507µs) by Moose::Meta::Attribute::try {...} at line 38 of Moose/Meta/Attribute.pm, avg 18µs/call sub resolve_metatrait_alias {
211 | 64 | 177µs | 64 | 24.0ms | return resolve_metaclass_alias( @_, trait => 1 ); # spent 24.0ms making 64 calls to Moose::Util::resolve_metaclass_alias, avg 374µs/call
212 |  |  |  |  | }
213 |  |  |  |  |
214 |  |  |  |  | # spent 16µs within Moose::Util::_build_alias_package_name which was called 4 times, avg 4µs/call: # 4 times (16µs+0s) by Moose::Util::resolve_metaclass_alias at line 233, avg 4µs/call sub _build_alias_package_name {
215 | 4 | 4µs |  |  | my ($type, $name, $trait) = @_;
216 | 4 | 14µs |  |  | return 'Moose::Meta::'
217 |  |  |  |  | . $type
218 |  |  |  |  | . '::Custom::'
219 |  |  |  |  | . ( $trait ? 'Trait::' : '' )
220 |  |  |  |  | . $name;
221 |  |  |  |  | }
222 |  |  |  |  |
223 |  |  |  |  | {
224 | 2 | 500ns |  |  | my %cache;
225 |  |  |  |  |
226 |  |  |  |  | # spent 24.0ms (374µs+23.6) within Moose::Util::resolve_metaclass_alias which was called 64 times, avg 374µs/call: # 64 times (374µs+23.6ms) by Moose::Util::resolve_metatrait_alias at line 211, avg 374µs/call sub resolve_metaclass_alias {
227 | 64 | 62µs |  |  | my ( $type, $metaclass_name, %options ) = @_;
228 |  |  |  |  |
229 | 64 | 57µs |  |  | my $cache_key = $type . q{ } . ( $options{trait} ? '-Trait' : '' );
230 | 64 | 225µs |  |  | return $cache{$cache_key}{$metaclass_name}
231 |  |  |  |  | if $cache{$cache_key}{$metaclass_name};
232 |  |  |  |  |
233 | 4 | 11µs | 4 | 16µs | my $possible_full_name = _build_alias_package_name( # spent 16µs making 4 calls to Moose::Util::_build_alias_package_name, avg 4µs/call
234 |  |  |  |  | $type, $metaclass_name, $options{trait}
235 |  |  |  |  | );
236 |  |  |  |  |
237 | 4 | 4µs |  |  | my @possible = ($possible_full_name, $metaclass_name);
238 | 4 | 2µs |  |  | for my $package (@possible) {
239 | 6 | 7µs | 6 | 0s | use_package_optimistically($package); # spent 571µs making 6 calls to Module::Runtime::use_package_optimistically, avg 95µs/call, recursion: max depth 1, sum of overlapping time 571µs
240 | 6 | 80µs | 12 | 23.0ms | if ($package->can('register_implementation')) { # spent 14.0ms making 1 call to Moose::Meta::Attribute::Custom::Trait::Hash::register_implementation # spent 9.00ms making 1 call to Moose::Meta::Attribute::Custom::Trait::Array::register_implementation # spent 24µs making 4 calls to Moose::Util::find_meta, avg 6µs/call # spent 13µs making 6 calls to UNIVERSAL::can, avg 2µs/call
241 |  |  |  |  | return $cache{$cache_key}{$metaclass_name} =
242 |  |  |  |  | $package->register_implementation;
243 |  |  |  |  | }
244 |  |  |  |  | elsif (find_meta($package)) {
245 |  |  |  |  | return $cache{$cache_key}{$metaclass_name} = $package;
246 |  |  |  |  | }
247 |  |  |  |  | }
248 |  |  |  |  |
249 |  |  |  |  | throw_exception( CannotLocatePackageInINC => possible_packages => _english_list_or(@possible),
250 |  |  |  |  | INC => \@INC,
251 |  |  |  |  | type => $type,
252 |  |  |  |  | metaclass_name => $metaclass_name,
253 |  |  |  |  | params => \%options
254 |  |  |  |  | );
255 |  |  |  |  | }
256 |  |  |  |  | }
257 |  |  |  |  |
258 |  |  |  |  | # spent 212µs (81+131) within Moose::Util::add_method_modifier which was called 9 times, avg 24µs/call: # 9 times (81µs+131µs) by Moose::Role::_add_method_modifier at line 65 of Moose/Role.pm, avg 24µs/call sub add_method_modifier {
259 | 9 | 4µs |  |  | my ( $class_or_obj, $modifier_name, $args ) = @_;
260 | 9 | 32µs | 9 | 10µs | my $meta # spent 10µs making 9 calls to UNIVERSAL::can, avg 1µs/call
261 |  |  |  |  | = $class_or_obj->can('add_before_method_modifier')
262 |  |  |  |  | ? $class_or_obj
263 |  |  |  |  | : find_meta($class_or_obj);
264 | 9 | 2µs |  |  | my $code = pop @{$args};
265 | 9 | 5µs |  |  | my $add_modifier_method = 'add_' . $modifier_name . '_method_modifier';
266 | 9 | 25µs |  |  | if ( my $method_modifier_type = ref( @{$args}[0] ) ) {
267 |  |  |  |  | if ( $method_modifier_type eq 'Regexp' ) {
268 |  |  |  |  | my @all_methods = $meta->get_all_methods;
269 |  |  |  |  | my @matched_methods
270 |  |  |  |  | = grep { $_->name =~ @{$args}[0] } @all_methods;
271 |  |  |  |  | $meta->$add_modifier_method( $_->name, $code )
272 |  |  |  |  | for @matched_methods;
273 |  |  |  |  | }
274 |  |  |  |  | elsif ($method_modifier_type eq 'ARRAY') {
275 |  |  |  |  | $meta->$add_modifier_method( $_, $code ) for @{$args->[0]};
276 |  |  |  |  | }
277 |  |  |  |  | else {
278 |  |  |  |  | throw_exception( IllegalMethodTypeToAddMethodModifier => class_or_object => $class_or_obj,
279 |  |  |  |  | modifier_name => $modifier_name,
280 |  |  |  |  | params => $args
281 |  |  |  |  | );
282 |  |  |  |  | }
283 |  |  |  |  | }
284 |  |  |  |  | else {
285 | 9 | 22µs | 9 | 122µs | $meta->$add_modifier_method( $_, $code ) for @{$args}; # spent 94µs making 7 calls to Moose::Meta::Role::add_around_method_modifier, avg 13µs/call # spent 27µs making 2 calls to Moose::Meta::Role::add_before_method_modifier, avg 14µs/call
286 |  |  |  |  | }
287 |  |  |  |  | }
288 |  |  |  |  |
289 |  |  |  |  | sub english_list {
290 |  |  |  |  | _english_list_and(@_);
291 |  |  |  |  | }
292 |  |  |  |  |
293 |  |  |  |  | sub _english_list_and {
294 |  |  |  |  | _english_list('and', \@_);
295 |  |  |  |  | }
296 |  |  |  |  |
297 |  |  |  |  | sub _english_list_or {
298 |  |  |  |  | _english_list('or', \@_);
299 |  |  |  |  | }
300 |  |  |  |  |
301 |  |  |  |  | sub _english_list {
302 |  |  |  |  | my ($conjunction, $items) = @_;
303 |  |  |  |  |
304 |  |  |  |  | my @items = sort @$items;
305 |  |  |  |  |
306 |  |  |  |  | return $items[0] if @items == 1;
307 |  |  |  |  | return "$items[0] $conjunction $items[1]" if @items == 2;
308 |  |  |  |  |
309 |  |  |  |  | my $tail = pop @items;
310 |  |  |  |  | my $list = join ', ', @items;
311 |  |  |  |  | $list .= ", $conjunction " . $tail;
312 |  |  |  |  |
313 |  |  |  |  | return $list;
314 |  |  |  |  | }
315 |  |  |  |  |
316 |  |  |  |  | # spent 527µs within Moose::Util::_caller_info which was called 62 times, avg 8µs/call: # 47 times (402µs+0s) by Moose::has at line 71 of Moose.pm, avg 9µs/call # 15 times (125µs+0s) by Moose::Role::has at line 47 of Moose/Role.pm, avg 8µs/call sub _caller_info {
317 | 62 | 38µs |  |  | my $level = @_ ? ($_[0] + 1) : 2;
318 | 62 | 13µs |  |  | my %info;
319 | 62 | 300µs |  |  | @info{qw(package file line)} = caller($level);
320 | 62 | 272µs |  |  | return %info;
321 |  |  |  |  | }
322 |  |  |  |  |
323 |  |  |  |  | sub _create_alias {
324 |  |  |  |  | my ($type, $name, $trait, $for) = @_;
325 |  |  |  |  | my $package = _build_alias_package_name($type, $name, $trait);
326 |  |  |  |  | Class::MOP::Class->initialize($package)->add_method(
327 |  |  |  |  | register_implementation => sub { $for }
328 |  |  |  |  | );
329 |  |  |  |  | }
330 |  |  |  |  |
331 |  |  |  |  | sub meta_attribute_alias {
332 |  |  |  |  | my ($to, $from) = @_;
333 |  |  |  |  | $from ||= caller;
334 |  |  |  |  | my $meta = Class::MOP::class_of($from);
335 |  |  |  |  | my $trait = $meta->isa('Moose::Meta::Role');
336 |  |  |  |  | _create_alias('Attribute', $to, $trait, $from);
337 |  |  |  |  | }
338 |  |  |  |  |
339 |  |  |  |  | sub meta_class_alias {
340 |  |  |  |  | my ($to, $from) = @_;
341 |  |  |  |  | $from ||= caller;
342 |  |  |  |  | my $meta = Class::MOP::class_of($from);
343 |  |  |  |  | my $trait = $meta->isa('Moose::Meta::Role');
344 |  |  |  |  | _create_alias('Class', $to, $trait, $from);
345 |  |  |  |  | }
346 |  |  |  |  |
347 |  |  |  |  | # spent 585ms (412µs+585) within Moose::Util::_load_user_class which was called 121 times, avg 4.83ms/call: # 60 times (212µs+584ms) by Moose::Meta::Class::superclasses at line 557 of Moose/Meta/Class.pm, avg 9.73ms/call # 42 times (124µs+393µs) by Moose::Meta::Role::apply at line 461 of Moose/Meta/Role.pm, avg 12µs/call # 19 times (76µs+323µs) by Moose::Meta::Role::Composite::apply_params at line 176 of Moose/Meta/Role/Composite.pm, avg 21µs/call sub _load_user_class {
348 | 121 | 38µs |  |  | my ($class, $opts) = @_;
349 | 121 | 349µs | 121 | 585ms | &use_package_optimistically( # spent 592ms making 121 calls to Module::Runtime::use_package_optimistically, avg 4.89ms/call, recursion: max depth 1, sum of overlapping time 7.00ms
350 |  |  |  |  | $class,
351 |  |  |  |  | $opts && $opts->{-version} ? $opts->{-version} : ()
352 |  |  |  |  | );
353 |  |  |  |  | }
354 |  |  |  |  |
355 |  |  |  |  | # XXX - this should be added to Params::Util
356 |  |  |  |  | sub _STRINGLIKE0 ($) {
357 |  |  |  |  | return 1 if _STRING( $_[0] );
358 |  |  |  |  | if ( blessed $_[0] ) {
359 |  |  |  |  | return overload::Method( $_[0], q{""} );
360 |  |  |  |  | }
361 |  |  |  |  |
362 |  |  |  |  | return 1 if defined $_[0] && $_[0] eq q{};
363 |  |  |  |  |
364 |  |  |  |  | return 0;
365 |  |  |  |  | }
366 |  |  |  |  |
367 |  |  |  |  | sub _reconcile_roles_for_metaclass {
368 |  |  |  |  | my ($class_meta_name, $super_meta_name) = @_;
369 |  |  |  |  |
370 |  |  |  |  | my @role_differences = _role_differences(
371 |  |  |  |  | $class_meta_name, $super_meta_name,
372 |  |  |  |  | );
373 |  |  |  |  |
374 |  |  |  |  | # handle the case where we need to fix compatibility between a class and
375 |  |  |  |  | # its parent, but all roles in the class are already also done by the
376 |  |  |  |  | # parent
377 |  |  |  |  | # see t/metaclasses/metaclass_compat_no_fixing_bug.t
378 |  |  |  |  | return $super_meta_name
379 |  |  |  |  | unless @role_differences;
380 |  |  |  |  |
381 |  |  |  |  | return Moose::Meta::Class->create_anon_class(
382 |  |  |  |  | superclasses => [$super_meta_name],
383 |  |  |  |  | roles => [map { $_->name } @role_differences],
384 |  |  |  |  | cache => 1,
385 |  |  |  |  | )->name;
386 |  |  |  |  | }
387 |  |  |  |  |
388 |  |  |  |  | sub _role_differences {
389 |  |  |  |  | my ($class_meta_name, $super_meta_name) = @_;
390 |  |  |  |  | my @super_role_metas = map {
391 |  |  |  |  | $_->isa('Moose::Meta::Role::Composite')
392 |  |  |  |  | ? (@{ $_->get_roles })
393 |  |  |  |  | : ($_)
394 |  |  |  |  | } $super_meta_name->meta->can('_roles_with_inheritance')
395 |  |  |  |  | ? $super_meta_name->meta->_roles_with_inheritance
396 |  |  |  |  | : $super_meta_name->meta->can('roles')
397 |  |  |  |  | ? @{ $super_meta_name->meta->roles }
398 |  |  |  |  | : ();
399 |  |  |  |  | my @role_metas = map {
400 |  |  |  |  | $_->isa('Moose::Meta::Role::Composite')
401 |  |  |  |  | ? (@{ $_->get_roles })
402 |  |  |  |  | : ($_)
403 |  |  |  |  | } $class_meta_name->meta->can('_roles_with_inheritance')
404 |  |  |  |  | ? $class_meta_name->meta->_roles_with_inheritance
405 |  |  |  |  | : $class_meta_name->meta->can('roles')
406 |  |  |  |  | ? @{ $class_meta_name->meta->roles }
407 |  |  |  |  | : ();
408 |  |  |  |  | my @differences;
409 |  |  |  |  | for my $role_meta (@role_metas) {
410 |  |  |  |  | push @differences, $role_meta
411 |  |  |  |  | unless any { $_->name eq $role_meta->name } @super_role_metas;
412 |  |  |  |  | }
413 |  |  |  |  | return @differences;
414 |  |  |  |  | }
415 |  |  |  |  |
416 |  |  |  |  | sub _classes_differ_by_roles_only {
417 |  |  |  |  | my ( $self_meta_name, $super_meta_name ) = @_;
418 |  |  |  |  |
419 |  |  |  |  | my $common_base_name
420 |  |  |  |  | = _find_common_base( $self_meta_name, $super_meta_name );
421 |  |  |  |  |
422 |  |  |  |  | return unless defined $common_base_name;
423 |  |  |  |  |
424 |  |  |  |  | my @super_meta_name_ancestor_names
425 |  |  |  |  | = _get_ancestors_until( $super_meta_name, $common_base_name );
426 |  |  |  |  | my @class_meta_name_ancestor_names
427 |  |  |  |  | = _get_ancestors_until( $self_meta_name, $common_base_name );
428 |  |  |  |  |
429 |  |  |  |  | return
430 |  |  |  |  | unless all { _is_role_only_subclass($_) }
431 |  |  |  |  | @super_meta_name_ancestor_names,
432 |  |  |  |  | @class_meta_name_ancestor_names;
433 |  |  |  |  |
434 |  |  |  |  | return 1;
435 |  |  |  |  | }
436 |  |  |  |  |
437 |  |  |  |  | sub _find_common_base {
438 |  |  |  |  | my ($meta1, $meta2) = map { Class::MOP::class_of($_) } @_;
439 |  |  |  |  | return unless defined $meta1 && defined $meta2;
440 |  |  |  |  |
441 |  |  |  |  | # FIXME? This doesn't account for multiple inheritance (not sure
442 |  |  |  |  | # if it needs to though). For example, if somewhere in $meta1's
443 |  |  |  |  | # history it inherits from both ClassA and ClassB, and $meta2
444 |  |  |  |  | # inherits from ClassB & ClassA, does it matter? And what crazy
445 |  |  |  |  | # fool would do that anyway?
446 |  |  |  |  |
447 |  |  |  |  | my %meta1_parents = map { $_ => 1 } $meta1->linearized_isa;
448 |  |  |  |  |
449 |  |  |  |  | return first { $meta1_parents{$_} } $meta2->linearized_isa;
450 |  |  |  |  | }
451 |  |  |  |  |
452 |  |  |  |  | sub _get_ancestors_until {
453 |  |  |  |  | my ($start_name, $until_name) = @_;
454 |  |  |  |  |
455 |  |  |  |  | my @ancestor_names;
456 |  |  |  |  | for my $ancestor_name (Class::MOP::class_of($start_name)->linearized_isa) {
457 |  |  |  |  | last if $ancestor_name eq $until_name;
458 |  |  |  |  | push @ancestor_names, $ancestor_name;
459 |  |  |  |  | }
460 |  |  |  |  | return @ancestor_names;
461 |  |  |  |  | }
462 |  |  |  |  |
463 |  |  |  |  | sub _is_role_only_subclass {
464 |  |  |  |  | my ($meta_name) = @_;
465 |  |  |  |  | my $meta = Class::MOP::Class->initialize($meta_name);
466 |  |  |  |  | my @parent_names = $meta->superclasses;
467 |  |  |  |  |
468 |  |  |  |  | # XXX: don't feel like messing with multiple inheritance here... what would
469 |  |  |  |  | # that even do?
470 |  |  |  |  | return unless @parent_names == 1;
471 |  |  |  |  | my ($parent_name) = @parent_names;
472 |  |  |  |  | my $parent_meta = Class::MOP::Class->initialize($parent_name);
473 |  |  |  |  |
474 |  |  |  |  | # only get the roles attached to this particular class, don't look at
475 |  |  |  |  | # superclasses
476 |  |  |  |  | my @roles = $meta->can('calculate_all_roles')
477 |  |  |  |  | ? $meta->calculate_all_roles
478 |  |  |  |  | : ();
479 |  |  |  |  |
480 |  |  |  |  | # it's obviously not a role-only subclass if it doesn't do any roles
481 |  |  |  |  | return unless @roles;
482 |  |  |  |  |
483 |  |  |  |  | # loop over all methods that are a part of the current class
484 |  |  |  |  | # (not inherited)
485 |  |  |  |  | for my $method ( $meta->_get_local_methods ) {
486 |  |  |  |  | # always ignore meta
487 |  |  |  |  | next if $method->isa('Class::MOP::Method::Meta');
488 |  |  |  |  | # we'll deal with attributes below
489 |  |  |  |  | next if $method->can('associated_attribute');
490 |  |  |  |  | # if the method comes from a role we consumed, ignore it
491 |  |  |  |  | next if $meta->can('does_role')
492 |  |  |  |  | && $meta->does_role($method->original_package_name);
493 |  |  |  |  | # FIXME - this really isn't right. Just because a modifier is
494 |  |  |  |  | # defined in a role doesn't mean it isn't _also_ defined in the
495 |  |  |  |  | # subclass.
496 |  |  |  |  | next if $method->isa('Class::MOP::Method::Wrapped')
497 |  |  |  |  | && (
498 |  |  |  |  | (!scalar($method->around_modifiers)
499 |  |  |  |  | || any { $_->has_around_method_modifiers($method->name) } @roles)
500 |  |  |  |  | && (!scalar($method->before_modifiers)
501 |  |  |  |  | || any { $_->has_before_method_modifiers($method->name) } @roles)
502 |  |  |  |  | && (!scalar($method->after_modifiers)
503 |  |  |  |  | || any { $_->has_after_method_modifiers($method->name) } @roles)
504 |  |  |  |  | );
505 |  |  |  |  |
506 |  |  |  |  | return 0;
507 |  |  |  |  | }
508 |  |  |  |  |
509 |  |  |  |  | # loop over all attributes that are a part of the current class
510 |  |  |  |  | # (not inherited)
511 |  |  |  |  | # FIXME - this really isn't right. Just because an attribute is
512 |  |  |  |  | # defined in a role doesn't mean it isn't _also_ defined in the
513 |  |  |  |  | # subclass.
514 |  |  |  |  | for my $attr (map { $meta->get_attribute($_) } $meta->get_attribute_list) {
515 |  |  |  |  | next if any { $_->has_attribute($attr->name) } @roles;
516 |  |  |  |  |
517 |  |  |  |  | return 0;
518 |  |  |  |  | }
519 |  |  |  |  |
520 |  |  |  |  | return 1;
521 |  |  |  |  | }
522 |  |  |  |  |
523 |  |  |  |  | sub _is_package_loaded {
524 |  |  |  |  | my ($package) = @_;
525 |  |  |  |  | defined $INC{module_notional_filename($package)};
526 |  |  |  |  | }
527 |  |  |  |  |
528 | 1 | 5µs |  |  | 1;
529 |  |  |  |  |
530 |  |  |  |  | # ABSTRACT: Utilities for working with Moose classes
531 |  |  |  |  |
532 |  |  |  |  | __END__