| File | /usr/lib/perl5/vendor_perl/5.10.1/i386-linux-thread-multi/Moose/Util/MetaRole.pm |
| Statements Executed | 1046 |
| Statement Execution Time | 18.1ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 11 | 2 | 1 | 6.96ms | 394ms | Moose::Util::MetaRole::_make_new_metaclass |
| 11 | 1 | 1 | 3.36ms | 4.98ms | Moose::Util::MetaRole::_fixup_old_style_args |
| 43 | 3 | 1 | 2.59ms | 297ms | Moose::Util::MetaRole::_make_new_class |
| 121 | 1 | 2 | 1.35ms | 1.35ms | Moose::Util::MetaRole::CORE:match (opcode) |
| 11 | 1 | 1 | 839µs | 401ms | Moose::Util::MetaRole::apply_metaroles |
| 8 | 1 | 1 | 456µs | 11.4ms | Moose::Util::MetaRole::apply_base_class_roles |
| 11 | 3 | 3 | 288µs | 288µs | Moose::Util::MetaRole::apply_metaclass_roles |
| 1 | 1 | 1 | 231µs | 641µs | Moose::Util::MetaRole::BEGIN@12 |
| 1 | 1 | 1 | 88µs | 199µs | Moose::Util::MetaRole::BEGIN@11 |
| 1 | 1 | 1 | 51µs | 63µs | Moose::Util::MetaRole::BEGIN@3 |
| 1 | 1 | 1 | 30µs | 195µs | Moose::Util::MetaRole::BEGIN@5 |
| 1 | 1 | 1 | 29µs | 90µs | Moose::Util::MetaRole::BEGIN@4 |
| 0 | 0 | 0 | 0s | 0s | Moose::Util::MetaRole::__ANON__[:103] |
| 0 | 0 | 0 | 0s | 0s | Moose::Util::MetaRole::__ANON__[:147] |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Moose::Util::MetaRole; | ||||
| 2 | |||||
| 3 | 3 | 83µs | 2 | 76µs | # spent 63µs (51+13) within Moose::Util::MetaRole::BEGIN@3 which was called
# once (51µs+13µs) by Moose::Exporter::BEGIN@13 at line 3 # spent 63µs making 1 call to Moose::Util::MetaRole::BEGIN@3
# spent 12µs making 1 call to strict::import |
| 4 | 3 | 86µs | 2 | 151µs | # spent 90µs (29+61) within Moose::Util::MetaRole::BEGIN@4 which was called
# once (29µs+61µs) by Moose::Exporter::BEGIN@13 at line 4 # spent 90µs making 1 call to Moose::Util::MetaRole::BEGIN@4
# spent 61µs making 1 call to warnings::import |
| 5 | 3 | 169µs | 2 | 359µs | # spent 195µs (30+164) within Moose::Util::MetaRole::BEGIN@5 which was called
# once (30µs+164µs) by Moose::Exporter::BEGIN@13 at line 5 # spent 195µs making 1 call to Moose::Util::MetaRole::BEGIN@5
# spent 164µs making 1 call to Exporter::import |
| 6 | |||||
| 7 | 1 | 3µs | our $VERSION = '1.01'; | ||
| 8 | 1 | 50µs | $VERSION = eval $VERSION; | ||
| 9 | 1 | 2µs | our $AUTHORITY = 'cpan:STEVAN'; | ||
| 10 | |||||
| 11 | 3 | 154µs | 2 | 309µs | # spent 199µs (88+111) within Moose::Util::MetaRole::BEGIN@11 which was called
# once (88µs+111µs) by Moose::Exporter::BEGIN@13 at line 11 # spent 199µs making 1 call to Moose::Util::MetaRole::BEGIN@11
# spent 110µs making 1 call to Exporter::import |
| 12 | 3 | 2.14ms | 2 | 1.05ms | # spent 641µs (231+410) within Moose::Util::MetaRole::BEGIN@12 which was called
# once (231µs+410µs) by Moose::Exporter::BEGIN@13 at line 12 # spent 641µs making 1 call to Moose::Util::MetaRole::BEGIN@12
# spent 410µs making 1 call to Exporter::import |
| 13 | |||||
| 14 | # spent 288µs within Moose::Util::MetaRole::apply_metaclass_roles which was called 11 times, avg 26µs/call:
# 8 times (258µs+0s) by MooseX::MethodAttributes::init_meta at line 32 of MooseX/MethodAttributes.pm, avg 32µs/call
# 2 times (21µs+0s) by MooseX::Role::WithOverloading::init_meta at line 24 of MooseX/Role/WithOverloading.pm, avg 10µs/call
# once (10µs+0s) by Class::MOP::Class:::around at line 14 of MooseX/Role/WithOverloading/Meta/Role/Application/ToRole.pm | ||||
| 15 | 11 | 212µs | 11 | 401ms | goto &apply_metaroles; # spent 401ms making 11 calls to Moose::Util::MetaRole::apply_metaroles, avg 36.4ms/call |
| 16 | } | ||||
| 17 | |||||
| 18 | # spent 401ms (839µs+400) within Moose::Util::MetaRole::apply_metaroles which was called 11 times, avg 36.4ms/call:
# 11 times (839µs+400ms) by Class::MOP::Class:::around or MooseX::MethodAttributes::init_meta or MooseX::Role::WithOverloading::init_meta at line 15, avg 36.4ms/call | ||||
| 19 | 55 | 772µs | my %args = @_; | ||
| 20 | |||||
| 21 | _fixup_old_style_args(\%args); # spent 4.98ms making 11 calls to Moose::Util::MetaRole::_fixup_old_style_args, avg 453µs/call | ||||
| 22 | Carp::cluck('applying') if $::D; | ||||
| 23 | my $for # spent 205µs making 8 calls to Class::MOP::class_of, avg 26µs/call
# spent 59µs making 11 calls to Scalar::Util::blessed, avg 5µs/call | ||||
| 24 | = blessed $args{for} | ||||
| 25 | ? $args{for} | ||||
| 26 | : Class::MOP::class_of( $args{for} ); | ||||
| 27 | |||||
| 28 | 8 | 147µs | 14 | 151ms | if ( $for->isa('Moose::Meta::Role') ) { # spent 151ms making 3 calls to Moose::Util::MetaRole::_make_new_metaclass, avg 50.4ms/call
# spent 191µs making 11 calls to UNIVERSAL::isa, avg 17µs/call |
| 29 | return _make_new_metaclass( $for, $args{role_metaroles}, 'role' ); | ||||
| 30 | } | ||||
| 31 | else { | ||||
| 32 | return _make_new_metaclass( $for, $args{class_metaroles}, 'class' ); # spent 243ms making 8 calls to Moose::Util::MetaRole::_make_new_metaclass, avg 30.4ms/call | ||||
| 33 | } | ||||
| 34 | } | ||||
| 35 | |||||
| 36 | # spent 4.98ms (3.36+1.63) within Moose::Util::MetaRole::_fixup_old_style_args which was called 11 times, avg 453µs/call:
# 11 times (3.36ms+1.63ms) by Moose::Util::MetaRole::apply_metaroles at line 21, avg 453µs/call | ||||
| 37 | 99 | 1.02ms | my $args = shift; | ||
| 38 | |||||
| 39 | return if $args->{class_metaroles} || $args->{roles_metaroles}; | ||||
| 40 | |||||
| 41 | $args->{for} = delete $args->{for_class} | ||||
| 42 | if exists $args->{for_class}; | ||||
| 43 | |||||
| 44 | my @old_keys = qw( | ||||
| 45 | attribute_metaclass_roles | ||||
| 46 | method_metaclass_roles | ||||
| 47 | wrapped_method_metaclass_roles | ||||
| 48 | instance_metaclass_roles | ||||
| 49 | constructor_class_roles | ||||
| 50 | destructor_class_roles | ||||
| 51 | error_class_roles | ||||
| 52 | |||||
| 53 | application_to_class_class_roles | ||||
| 54 | application_to_role_class_roles | ||||
| 55 | application_to_instance_class_roles | ||||
| 56 | application_role_summation_class_roles | ||||
| 57 | ); | ||||
| 58 | |||||
| 59 | my $for # spent 160µs making 8 calls to Class::MOP::class_of, avg 20µs/call
# spent 54µs making 11 calls to Scalar::Util::blessed, avg 5µs/call | ||||
| 60 | = blessed $args->{for} | ||||
| 61 | ? $args->{for} | ||||
| 62 | : Class::MOP::class_of( $args->{for} ); | ||||
| 63 | |||||
| 64 | my $top_key; | ||||
| 65 | 22 | 106µs | 11 | 59µs | if ( $for->isa('Moose::Meta::Class') ) { # spent 59µs making 11 calls to UNIVERSAL::isa, avg 5µs/call |
| 66 | $top_key = 'class_metaroles'; | ||||
| 67 | |||||
| 68 | $args->{class_metaroles}{class} = delete $args->{metaclass_roles} | ||||
| 69 | if exists $args->{metaclass_roles}; | ||||
| 70 | } | ||||
| 71 | else { | ||||
| 72 | $top_key = 'role_metaroles'; | ||||
| 73 | |||||
| 74 | $args->{role_metaroles}{role} = delete $args->{metaclass_roles} | ||||
| 75 | if exists $args->{metaclass_roles}; | ||||
| 76 | } | ||||
| 77 | |||||
| 78 | for my $old_key (@old_keys) { | ||||
| 79 | 242 | 3.50ms | 121 | 1.35ms | my ($new_key) = $old_key =~ /^(.+)_(?:class|metaclass)_roles$/; # spent 1.35ms making 121 calls to Moose::Util::MetaRole::CORE:match, avg 11µs/call |
| 80 | |||||
| 81 | $args->{$top_key}{$new_key} = delete $args->{$old_key} | ||||
| 82 | if exists $args->{$old_key}; | ||||
| 83 | } | ||||
| 84 | |||||
| 85 | return; | ||||
| 86 | } | ||||
| 87 | |||||
| 88 | # spent 394ms (6.96+387) within Moose::Util::MetaRole::_make_new_metaclass which was called 11 times, avg 35.9ms/call:
# 8 times (3.50ms+240ms) by Moose::Util::MetaRole::apply_metaroles at line 32, avg 30.4ms/call
# 3 times (3.46ms+148ms) by Moose::Util::MetaRole::apply_metaroles at line 28, avg 50.4ms/call | ||||
| 89 | 99 | 877µs | my $for = shift; | ||
| 90 | my $roles = shift; | ||||
| 91 | my $primary = shift; | ||||
| 92 | |||||
| 93 | return $for unless keys %{$roles}; | ||||
| 94 | |||||
| 95 | my $new_metaclass # spent 112ms making 10 calls to Moose::Util::MetaRole::_make_new_class, avg 11.2ms/call
# spent 5µs making 1 call to Scalar::Util::blessed | ||||
| 96 | = exists $roles->{$primary} | ||||
| 97 | ? _make_new_class( ref $for, $roles->{$primary} ) | ||||
| 98 | : blessed $for; | ||||
| 99 | |||||
| 100 | my %classes; | ||||
| 101 | |||||
| 102 | for my $key ( grep { $_ ne $primary } keys %{$roles} ) { | ||||
| 103 | 25 | 601µs | my $attr = first {$_} | ||
| 104 | 125 | 3.81ms | 125 | 34.6ms | map { $for->meta->find_attribute_by_name($_) } ( # spent 31.0ms making 50 calls to Class::MOP::Class::find_attribute_by_name, avg 620µs/call
# spent 1.44ms making 28 calls to Class::MOP::Class::__ANON__::SERIAL::5::meta, avg 52µs/call
# spent 1.06ms making 12 calls to Moose::Meta::Role::meta, avg 88µs/call
# spent 477µs making 25 calls to List::Util::first, avg 19µs/call
# spent 307µs making 4 calls to Class::MOP::Object::meta, avg 77µs/call
# spent 284µs making 6 calls to Class::MOP::Class::__ANON__::SERIAL::1::meta, avg 47µs/call |
| 105 | $key . '_metaclass', | ||||
| 106 | $key . '_class' | ||||
| 107 | ); | ||||
| 108 | |||||
| 109 | my $reader = $attr->get_read_method; # spent 1.38ms making 25 calls to Class::MOP::Attribute::get_read_method, avg 55µs/call | ||||
| 110 | |||||
| 111 | $classes{ $attr->init_arg } # spent 175ms making 25 calls to Moose::Util::MetaRole::_make_new_class, avg 7.02ms/call
# spent 378µs making 25 calls to Class::MOP::Mixin::AttributeCore::init_arg, avg 15µs/call
# spent 244µs making 8 calls to Class::MOP::Mixin::HasMethods::wrapped_method_metaclass, avg 31µs/call
# spent 61µs making 8 calls to Class::MOP::Mixin::HasMethods::method_metaclass, avg 8µs/call
# spent 36µs making 3 calls to Moose::Meta::Role::application_to_class_class, avg 12µs/call
# spent 34µs making 3 calls to Moose::Meta::Role::application_to_instance_class, avg 11µs/call
# spent 30µs making 3 calls to Moose::Meta::Role::application_to_role_class, avg 10µs/call | ||||
| 112 | = _make_new_class( $for->$reader(), $roles->{$key} ); | ||||
| 113 | } | ||||
| 114 | |||||
| 115 | my $new_meta = $new_metaclass->reinitialize( $for, %classes ); # spent 42.6ms making 8 calls to Moose::Meta::Class::reinitialize, avg 5.32ms/call
# spent 21.1ms making 3 calls to Moose::Meta::Role::reinitialize, avg 7.05ms/call | ||||
| 116 | |||||
| 117 | return $new_meta; | ||||
| 118 | } | ||||
| 119 | |||||
| 120 | # spent 11.4ms (456µs+10.9) within Moose::Util::MetaRole::apply_base_class_roles which was called 8 times, avg 1.42ms/call:
# 8 times (456µs+10.9ms) by MooseX::MethodAttributes::init_meta at line 40 of MooseX/MethodAttributes.pm, avg 1.42ms/call | ||||
| 121 | 40 | 446µs | my %args = @_; | ||
| 122 | |||||
| 123 | my $for = $args{for} || $args{for_class}; | ||||
| 124 | |||||
| 125 | my $meta = Class::MOP::class_of($for); # spent 152µs making 8 calls to Class::MOP::class_of, avg 19µs/call | ||||
| 126 | |||||
| 127 | my $new_base = _make_new_class( # spent 9.76ms making 8 calls to Moose::Util::MetaRole::_make_new_class, avg 1.22ms/call
# spent 994µs making 8 calls to Moose::Meta::Class::superclasses, avg 124µs/call | ||||
| 128 | $for, | ||||
| 129 | $args{roles}, | ||||
| 130 | [ $meta->superclasses() ], | ||||
| 131 | ); | ||||
| 132 | |||||
| 133 | $meta->superclasses($new_base) # spent 28µs making 8 calls to Class::MOP::Package::name, avg 4µs/call | ||||
| 134 | if $new_base ne $meta->name(); | ||||
| 135 | } | ||||
| 136 | |||||
| 137 | # spent 297ms (2.59+294) within Moose::Util::MetaRole::_make_new_class which was called 43 times, avg 6.90ms/call:
# 25 times (1.45ms+174ms) by Moose::Util::MetaRole::_make_new_metaclass at line 111, avg 7.02ms/call
# 10 times (707µs+111ms) by Moose::Util::MetaRole::_make_new_metaclass at line 95, avg 11.2ms/call
# 8 times (427µs+9.34ms) by Moose::Util::MetaRole::apply_base_class_roles at line 127, avg 1.22ms/call | ||||
| 138 | 276 | 3.22ms | my $existing_class = shift; | ||
| 139 | my $roles = shift; | ||||
| 140 | my $superclasses = shift || [$existing_class]; | ||||
| 141 | |||||
| 142 | return $existing_class unless $roles; | ||||
| 143 | |||||
| 144 | my $meta = Class::MOP::Class->initialize($existing_class); # spent 1.41ms making 43 calls to Class::MOP::Class::initialize, avg 33µs/call | ||||
| 145 | |||||
| 146 | return $existing_class | ||||
| 147 | 25 | 639µs | 25 | 17.0ms | if $meta->can('does_role') && all { $meta->does_role($_) } # spent 17.0ms making 25 calls to Moose::Meta::Class::does_role, avg 681µs/call |
| 148 | grep { !ref $_ } @{$roles}; # spent 17.6ms making 25 calls to List::MoreUtils::all, avg 706µs/call
# spent 512µs making 43 calls to UNIVERSAL::can, avg 12µs/call | ||||
| 149 | |||||
| 150 | return Moose::Meta::Class->create_anon_class( # spent 275ms making 18 calls to Moose::Meta::Class::create_anon_class, avg 15.3ms/call
# spent 129µs making 18 calls to Class::MOP::Package::name, avg 7µs/call | ||||
| 151 | superclasses => $superclasses, | ||||
| 152 | roles => $roles, | ||||
| 153 | cache => 1, | ||||
| 154 | )->name(); | ||||
| 155 | } | ||||
| 156 | |||||
| 157 | 1 | 10µs | 1; | ||
| 158 | |||||
| 159 | __END__ | ||||
| 160 | |||||
| 161 | =head1 NAME | ||||
| 162 | |||||
| 163 | Moose::Util::MetaRole - Apply roles to any metaclass, as well as the object base class | ||||
| 164 | |||||
| 165 | =head1 SYNOPSIS | ||||
| 166 | |||||
| 167 | package MyApp::Moose; | ||||
| 168 | |||||
| 169 | use Moose (); | ||||
| 170 | use Moose::Exporter; | ||||
| 171 | use Moose::Util::MetaRole; | ||||
| 172 | |||||
| 173 | use MyApp::Role::Meta::Class; | ||||
| 174 | use MyApp::Role::Meta::Method::Constructor; | ||||
| 175 | use MyApp::Role::Object; | ||||
| 176 | |||||
| 177 | Moose::Exporter->setup_import_methods( also => 'Moose' ); | ||||
| 178 | |||||
| 179 | sub init_meta { | ||||
| 180 | shift; | ||||
| 181 | my %args = @_; | ||||
| 182 | |||||
| 183 | Moose->init_meta(%args); | ||||
| 184 | |||||
| 185 | Moose::Util::MetaRole::apply_metaroles( | ||||
| 186 | for => $args{for_class}, | ||||
| 187 | class_metaroles => { | ||||
| 188 | class => => ['MyApp::Role::Meta::Class'], | ||||
| 189 | constructor => ['MyApp::Role::Meta::Method::Constructor'], | ||||
| 190 | }, | ||||
| 191 | ); | ||||
| 192 | |||||
| 193 | Moose::Util::MetaRole::apply_base_class_roles( | ||||
| 194 | for => $args{for_class}, | ||||
| 195 | roles => ['MyApp::Role::Object'], | ||||
| 196 | ); | ||||
| 197 | |||||
| 198 | return $args{for_class}->meta(); | ||||
| 199 | } | ||||
| 200 | |||||
| 201 | =head1 DESCRIPTION | ||||
| 202 | |||||
| 203 | This utility module is designed to help authors of Moose extensions | ||||
| 204 | write extensions that are able to cooperate with other Moose | ||||
| 205 | extensions. To do this, you must write your extensions as roles, which | ||||
| 206 | can then be dynamically applied to the caller's metaclasses. | ||||
| 207 | |||||
| 208 | This module makes sure to preserve any existing superclasses and roles | ||||
| 209 | already set for the meta objects, which means that any number of | ||||
| 210 | extensions can apply roles in any order. | ||||
| 211 | |||||
| 212 | =head1 USAGE | ||||
| 213 | |||||
| 214 | B<It is very important that you only call this module's functions when | ||||
| 215 | your module is imported by the caller>. The process of applying roles | ||||
| 216 | to the metaclass reinitializes the metaclass object, which wipes out | ||||
| 217 | any existing attributes already defined. However, as long as you do | ||||
| 218 | this when your module is imported, the caller should not have any | ||||
| 219 | attributes defined yet. | ||||
| 220 | |||||
| 221 | The easiest way to ensure that this happens is to use | ||||
| 222 | L<Moose::Exporter>, which can generate the appropriate C<init_meta> | ||||
| 223 | method for you, and make sure it is called when imported. | ||||
| 224 | |||||
| 225 | =head1 FUNCTIONS | ||||
| 226 | |||||
| 227 | This module provides two functions. | ||||
| 228 | |||||
| 229 | =head2 apply_metaroles( ... ) | ||||
| 230 | |||||
| 231 | This function will apply roles to one or more metaclasses for the specified | ||||
| 232 | class. It will return a new metaclass object for the class or role passed in | ||||
| 233 | the "for" parameter. | ||||
| 234 | |||||
| 235 | It accepts the following parameters: | ||||
| 236 | |||||
| 237 | =over 4 | ||||
| 238 | |||||
| 239 | =item * for => $name | ||||
| 240 | |||||
| 241 | This specifies the class or for which to alter the meta classes. This can be a | ||||
| 242 | package name, or an appropriate meta-object (a L<Moose::Meta::Class> or | ||||
| 243 | L<Moose::Meta::Role>). | ||||
| 244 | |||||
| 245 | =item * class_metaroles => \%roles | ||||
| 246 | |||||
| 247 | This is a hash reference specifying which metaroles will be applied to the | ||||
| 248 | class metaclass and its contained metaclasses and helper classes. | ||||
| 249 | |||||
| 250 | Each key should in turn point to an array reference of role names. | ||||
| 251 | |||||
| 252 | It accepts the following keys: | ||||
| 253 | |||||
| 254 | =over 8 | ||||
| 255 | |||||
| 256 | =item class | ||||
| 257 | |||||
| 258 | =item attribute | ||||
| 259 | |||||
| 260 | =item method | ||||
| 261 | |||||
| 262 | =item wrapped_method | ||||
| 263 | |||||
| 264 | =item instance | ||||
| 265 | |||||
| 266 | =item constructor | ||||
| 267 | |||||
| 268 | =item destructor | ||||
| 269 | |||||
| 270 | =item error | ||||
| 271 | |||||
| 272 | =back | ||||
| 273 | |||||
| 274 | =item * role_metaroles => \%roles | ||||
| 275 | |||||
| 276 | This is a hash reference specifying which metaroles will be applied to the | ||||
| 277 | role metaclass and its contained metaclasses and helper classes. | ||||
| 278 | |||||
| 279 | It accepts the following keys: | ||||
| 280 | |||||
| 281 | =over 8 | ||||
| 282 | |||||
| 283 | =item role | ||||
| 284 | |||||
| 285 | =item attribute | ||||
| 286 | |||||
| 287 | =item method | ||||
| 288 | |||||
| 289 | =item required_method | ||||
| 290 | |||||
| 291 | =item conflicting_method | ||||
| 292 | |||||
| 293 | =item application_to_class | ||||
| 294 | |||||
| 295 | =item application_to_role | ||||
| 296 | |||||
| 297 | =item application_to_instance | ||||
| 298 | |||||
| 299 | =item application_role_summation | ||||
| 300 | |||||
| 301 | =back | ||||
| 302 | |||||
| 303 | =back | ||||
| 304 | |||||
| 305 | =head2 apply_base_class_roles( for => $class, roles => \@roles ) | ||||
| 306 | |||||
| 307 | This function will apply the specified roles to the object's base class. | ||||
| 308 | |||||
| 309 | =head1 BUGS | ||||
| 310 | |||||
| 311 | See L<Moose/BUGS> for details on reporting bugs. | ||||
| 312 | |||||
| 313 | =head1 AUTHOR | ||||
| 314 | |||||
| 315 | Dave Rolsky E<lt>autarch@urth.orgE<gt> | ||||
| 316 | |||||
| 317 | =head1 COPYRIGHT AND LICENSE | ||||
| 318 | |||||
| 319 | Copyright 2009 by Infinity Interactive, Inc. | ||||
| 320 | |||||
| 321 | L<http://www.iinteractive.com> | ||||
| 322 | |||||
| 323 | This library is free software; you can redistribute it and/or modify | ||||
| 324 | it under the same terms as Perl itself. | ||||
| 325 | |||||
| 326 | =cut | ||||
# spent 1.35ms within Moose::Util::MetaRole::CORE:match which was called 121 times, avg 11µs/call:
# 121 times (1.35ms+0s) by Moose::Util::MetaRole::_fixup_old_style_args at line 79 of Moose/Util/MetaRole.pm, avg 11µs/call |