| Filename | /usr/local/lib/perl/5.10.1/Mouse/Meta/Module.pm |
| Statements | Executed 227 statements in 2.51ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 65 | 4 | 3 | 501µs | 501µs | Mouse::Meta::Module::add_method (xsub) |
| 58 | 3 | 1 | 235µs | 370µs | Mouse::Meta::Module::initialize |
| 30 | 4 | 3 | 56µs | 56µs | Mouse::Meta::Module::_get_metaclass_by_name |
| 1 | 1 | 1 | 16µs | 66µs | Mouse::Meta::Module::BEGIN@2 |
| 1 | 1 | 1 | 10µs | 24µs | Mouse::Meta::Module::BEGIN@299 |
| 1 | 1 | 1 | 10µs | 23µs | Mouse::Meta::Module::BEGIN@220 |
| 1 | 1 | 1 | 5µs | 5µs | Mouse::Meta::Module::BEGIN@4 |
| 1 | 1 | 1 | 5µs | 5µs | Mouse::Meta::Module::BEGIN@5 |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::DESTROY |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::__ANON__[:14] |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::__ANON__[:232] |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::_class_of |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::_collect_methods |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::_get_all_metaclass_instances |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::_get_all_metaclass_names |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::_get_method_body |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::create |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::get_attribute |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::get_attribute_list |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::get_attribute_map |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::get_method |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::get_method_body |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::get_method_list |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::has_attribute |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::has_method |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::reinitialize |
| 0 | 0 | 0 | 0s | 0s | Mouse::Meta::Module::remove_attribute |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Mouse::Meta::Module; | ||||
| 2 | 3 | 35µs | 2 | 115µs | # spent 66µs (16+50) within Mouse::Meta::Module::BEGIN@2 which was called:
# once (16µs+50µs) by Mouse::BEGIN@4 at line 2 # spent 66µs making 1 call to Mouse::Meta::Module::BEGIN@2
# spent 50µs making 1 call to Mouse::Exporter::do_import |
| 3 | |||||
| 4 | 3 | 28µs | 1 | 5µs | # spent 5µs within Mouse::Meta::Module::BEGIN@4 which was called:
# once (5µs+0s) by Mouse::BEGIN@4 at line 4 # spent 5µs making 1 call to Mouse::Meta::Module::BEGIN@4 |
| 5 | 3 | 1.42ms | 1 | 5µs | # spent 5µs within Mouse::Meta::Module::BEGIN@5 which was called:
# once (5µs+0s) by Mouse::BEGIN@4 at line 5 # spent 5µs making 1 call to Mouse::Meta::Module::BEGIN@5 |
| 6 | |||||
| 7 | 1 | 300ns | my %METAS; | ||
| 8 | |||||
| 9 | 3 | 15µs | if(Mouse::Util::MOUSE_XS){ | ||
| 10 | # register meta storage for performance | ||||
| 11 | 1 | 3µs | Mouse::Util::__register_metaclass_storage(\%METAS, 0); # spent 3µs making 1 call to Mouse::Util::__register_metaclass_storage | ||
| 12 | |||||
| 13 | # ensure thread safety | ||||
| 14 | *CLONE = sub { Mouse::Util::__register_metaclass_storage(\%METAS, 1) }; | ||||
| 15 | } | ||||
| 16 | |||||
| 17 | # spent 370µs (235+135) within Mouse::Meta::Module::initialize which was called 58 times, avg 6µs/call:
# 45 times (149µs+0s) by Mouse::has at line 45 of Mouse.pm, avg 3µs/call
# 8 times (69µs+135µs) by Mouse::init_meta at line 133 of Mouse.pm, avg 26µs/call
# 5 times (17µs+0s) by MongoDB::Collection::meta or MongoDB::Connection::meta or MongoDB::Cursor::meta or MongoDB::Database::meta or MongoDB::OID::meta at line 136 of Mouse.pm, avg 3µs/call | ||||
| 18 | 174 | 304µs | my($class, $package_name, @args) = @_; | ||
| 19 | |||||
| 20 | ($package_name && !ref($package_name)) | ||||
| 21 | || $class->throw_error("You must pass a package name and it cannot be blessed"); | ||||
| 22 | |||||
| 23 | 8 | 135µs | return $METAS{$package_name} # spent 135µs making 8 calls to Mouse::Meta::Class::_construct_meta, avg 17µs/call | ||
| 24 | ||= $class->_construct_meta(package => $package_name, @args); | ||||
| 25 | } | ||||
| 26 | |||||
| 27 | sub reinitialize { | ||||
| 28 | my($class, $package_name, @args) = @_; | ||||
| 29 | |||||
| 30 | $package_name = $package_name->name if ref $package_name; | ||||
| 31 | |||||
| 32 | ($package_name && !ref($package_name)) | ||||
| 33 | || $class->throw_error("You must pass a package name and it cannot be blessed"); | ||||
| 34 | |||||
| 35 | if(exists $METAS{$package_name}) { | ||||
| 36 | unshift @args, %{ $METAS{$package_name} }; | ||||
| 37 | } | ||||
| 38 | delete $METAS{$package_name}; | ||||
| 39 | return $class->initialize($package_name, @args); | ||||
| 40 | } | ||||
| 41 | |||||
| 42 | sub _class_of{ | ||||
| 43 | my($class_or_instance) = @_; | ||||
| 44 | return undef unless defined $class_or_instance; | ||||
| 45 | return $METAS{ ref($class_or_instance) || $class_or_instance }; | ||||
| 46 | } | ||||
| 47 | |||||
| 48 | # Means of accessing all the metaclasses that have | ||||
| 49 | # been initialized thus far. | ||||
| 50 | # The public versions are aliased into Mouse::Util::*. | ||||
| 51 | #sub _get_all_metaclasses { %METAS } | ||||
| 52 | sub _get_all_metaclass_instances { values %METAS } | ||||
| 53 | sub _get_all_metaclass_names { keys %METAS } | ||||
| 54 | 30 | 104µs | # spent 56µs within Mouse::Meta::Module::_get_metaclass_by_name which was called 30 times, avg 2µs/call:
# 14 times (25µs+0s) by Any::Moose::_backer_of at line 103 of Any/Moose.pm, avg 2µs/call
# 8 times (15µs+0s) by Mouse::Meta::Class::superclasses at line 59 of Mouse/Meta/Class.pm, avg 2µs/call
# 6 times (12µs+0s) by Mouse::Meta::Class::_calculate_all_attributes at line 260 of Mouse/Meta/Class.pm, avg 2µs/call
# 2 times (5µs+0s) by Mouse::Util::TypeConstraints::_find_or_create_regular_type at line 270 of Mouse/Util/TypeConstraints.pm, avg 2µs/call | ||
| 55 | #sub _store_metaclass_by_name { $METAS{$_[0]} = $_[1] } | ||||
| 56 | #sub _weaken_metaclass { weaken($METAS{$_[0]}) } | ||||
| 57 | #sub _does_metaclass_exist { defined $METAS{$_[0]} } | ||||
| 58 | #sub _remove_metaclass_by_name { delete $METAS{$_[0]} } | ||||
| 59 | |||||
| 60 | sub name; | ||||
| 61 | |||||
| 62 | sub namespace; | ||||
| 63 | |||||
| 64 | # add_attribute is an abstract method | ||||
| 65 | |||||
| 66 | sub get_attribute_map { # DEPRECATED | ||||
| 67 | Carp::cluck('get_attribute_map() has been deprecated. Use get_attribute_list() and get_attribute() instead'); | ||||
| 68 | return $_[0]->{attributes}; | ||||
| 69 | } | ||||
| 70 | |||||
| 71 | sub has_attribute { exists $_[0]->{attributes}->{$_[1]} } | ||||
| 72 | sub get_attribute { $_[0]->{attributes}->{$_[1]} } | ||||
| 73 | sub remove_attribute { delete $_[0]->{attributes}->{$_[1]} } | ||||
| 74 | |||||
| 75 | sub get_attribute_list{ keys %{$_[0]->{attributes}} } | ||||
| 76 | |||||
| 77 | # XXX: not completely compatible with Moose | ||||
| 78 | 1 | 9µs | my %foreign = map{ $_ => undef } qw( | ||
| 79 | Mouse Mouse::Role Mouse::Util Mouse::Util::TypeConstraints | ||||
| 80 | Carp Scalar::Util List::Util | ||||
| 81 | ); | ||||
| 82 | sub _get_method_body { | ||||
| 83 | my($self, $method_name) = @_; | ||||
| 84 | my $code = Mouse::Util::get_code_ref($self->{package}, $method_name); | ||||
| 85 | return $code && !exists $foreign{ Mouse::Util::get_code_package($code) } | ||||
| 86 | ? $code | ||||
| 87 | : undef; | ||||
| 88 | } | ||||
| 89 | |||||
| 90 | sub add_method; | ||||
| 91 | |||||
| 92 | sub has_method { | ||||
| 93 | my($self, $method_name) = @_; | ||||
| 94 | defined($method_name) | ||||
| 95 | or $self->throw_error('You must define a method name'); | ||||
| 96 | |||||
| 97 | return defined( $self->{methods}{$method_name} ) | ||||
| 98 | || defined( $self->_get_method_body($method_name) ); | ||||
| 99 | } | ||||
| 100 | |||||
| 101 | sub get_method_body { | ||||
| 102 | my($self, $method_name) = @_; | ||||
| 103 | defined($method_name) | ||||
| 104 | or $self->throw_error('You must define a method name'); | ||||
| 105 | |||||
| 106 | return $self->{methods}{$method_name} | ||||
| 107 | ||= $self->_get_method_body($method_name); | ||||
| 108 | } | ||||
| 109 | |||||
| 110 | sub get_method { | ||||
| 111 | my($self, $method_name) = @_; | ||||
| 112 | |||||
| 113 | if(my $code = $self->get_method_body($method_name)){ | ||||
| 114 | return Mouse::Util::load_class($self->method_metaclass)->wrap( | ||||
| 115 | body => $code, | ||||
| 116 | name => $method_name, | ||||
| 117 | package => $self->name, | ||||
| 118 | associated_metaclass => $self, | ||||
| 119 | ); | ||||
| 120 | } | ||||
| 121 | |||||
| 122 | return undef; | ||||
| 123 | } | ||||
| 124 | |||||
| 125 | sub get_method_list { | ||||
| 126 | my($self) = @_; | ||||
| 127 | |||||
| 128 | return grep { $self->has_method($_) } keys %{ $self->namespace }; | ||||
| 129 | } | ||||
| 130 | |||||
| 131 | sub _collect_methods { # Mouse specific, used for method modifiers | ||||
| 132 | my($meta, @args) = @_; | ||||
| 133 | |||||
| 134 | my @methods; | ||||
| 135 | foreach my $arg(@args){ | ||||
| 136 | if(my $type = ref $arg){ | ||||
| 137 | if($type eq 'Regexp'){ | ||||
| 138 | push @methods, grep { $_ =~ $arg } $meta->get_all_method_names; | ||||
| 139 | } | ||||
| 140 | elsif($type eq 'ARRAY'){ | ||||
| 141 | push @methods, @{$arg}; | ||||
| 142 | } | ||||
| 143 | else{ | ||||
| 144 | my $subname = ( caller(1) )[3]; | ||||
| 145 | $meta->throw_error( | ||||
| 146 | sprintf( | ||||
| 147 | 'Methods passed to %s must be provided as a list,' | ||||
| 148 | . ' ArrayRef or regular expression, not %s', | ||||
| 149 | $subname, | ||||
| 150 | $type, | ||||
| 151 | ) | ||||
| 152 | ); | ||||
| 153 | } | ||||
| 154 | } | ||||
| 155 | else{ | ||||
| 156 | push @methods, $arg; | ||||
| 157 | } | ||||
| 158 | } | ||||
| 159 | return @methods; | ||||
| 160 | } | ||||
| 161 | |||||
| 162 | 1 | 400ns | my $ANON_SERIAL = 0; # anonymous class/role id | ||
| 163 | 1 | 200ns | my %IMMORTALS; # immortal anonymous classes | ||
| 164 | |||||
| 165 | sub create { | ||||
| 166 | my($self, $package_name, %options) = @_; | ||||
| 167 | |||||
| 168 | my $class = ref($self) || $self; | ||||
| 169 | $self->throw_error('You must pass a package name') if @_ < 2; | ||||
| 170 | |||||
| 171 | my $superclasses; | ||||
| 172 | if(exists $options{superclasses}){ | ||||
| 173 | if(Mouse::Util::is_a_metarole($self)){ | ||||
| 174 | delete $options{superclasses}; | ||||
| 175 | } | ||||
| 176 | else{ | ||||
| 177 | $superclasses = delete $options{superclasses}; | ||||
| 178 | (ref $superclasses eq 'ARRAY') | ||||
| 179 | || $self->throw_error("You must pass an ARRAY ref of superclasses"); | ||||
| 180 | } | ||||
| 181 | } | ||||
| 182 | |||||
| 183 | my $attributes = delete $options{attributes}; | ||||
| 184 | if(defined $attributes){ | ||||
| 185 | (ref $attributes eq 'ARRAY' || ref $attributes eq 'HASH') | ||||
| 186 | || $self->throw_error("You must pass an ARRAY ref of attributes"); | ||||
| 187 | } | ||||
| 188 | my $methods = delete $options{methods}; | ||||
| 189 | if(defined $methods){ | ||||
| 190 | (ref $methods eq 'HASH') | ||||
| 191 | || $self->throw_error("You must pass a HASH ref of methods"); | ||||
| 192 | } | ||||
| 193 | my $roles = delete $options{roles}; | ||||
| 194 | if(defined $roles){ | ||||
| 195 | (ref $roles eq 'ARRAY') | ||||
| 196 | || $self->throw_error("You must pass an ARRAY ref of roles"); | ||||
| 197 | } | ||||
| 198 | my $mortal; | ||||
| 199 | my $cache_key; | ||||
| 200 | |||||
| 201 | if(!defined $package_name){ # anonymous | ||||
| 202 | $mortal = !$options{cache}; | ||||
| 203 | |||||
| 204 | # anonymous but immortal | ||||
| 205 | if(!$mortal){ | ||||
| 206 | # something like Super::Class|Super::Class::2=Role|Role::1 | ||||
| 207 | $cache_key = join '=' => ( | ||||
| 208 | join('|', @{$superclasses || []}), | ||||
| 209 | join('|', sort @{$roles || []}), | ||||
| 210 | ); | ||||
| 211 | return $IMMORTALS{$cache_key} if exists $IMMORTALS{$cache_key}; | ||||
| 212 | } | ||||
| 213 | $options{anon_serial_id} = ++$ANON_SERIAL; | ||||
| 214 | $package_name = $class . '::__ANON__::' . $ANON_SERIAL; | ||||
| 215 | } | ||||
| 216 | |||||
| 217 | |||||
| 218 | # instantiate a module | ||||
| 219 | { | ||||
| 220 | 3 | 523µs | 2 | 36µs | # spent 23µs (10+13) within Mouse::Meta::Module::BEGIN@220 which was called:
# once (10µs+13µs) by Mouse::BEGIN@4 at line 220 # spent 23µs making 1 call to Mouse::Meta::Module::BEGIN@220
# spent 13µs making 1 call to strict::unimport |
| 221 | ${ $package_name . '::VERSION' } = delete $options{version} if exists $options{version}; | ||||
| 222 | ${ $package_name . '::AUTHORITY' } = delete $options{authority} if exists $options{authority}; | ||||
| 223 | } | ||||
| 224 | |||||
| 225 | my $meta = $self->initialize( $package_name, %options); | ||||
| 226 | |||||
| 227 | Scalar::Util::weaken($METAS{$package_name}) | ||||
| 228 | if $mortal; | ||||
| 229 | |||||
| 230 | $meta->add_method(meta => sub { | ||||
| 231 | $self->initialize(ref($_[0]) || $_[0]); | ||||
| 232 | }); | ||||
| 233 | |||||
| 234 | $meta->superclasses(@{$superclasses}) | ||||
| 235 | if defined $superclasses; | ||||
| 236 | |||||
| 237 | # NOTE: | ||||
| 238 | # process attributes first, so that they can | ||||
| 239 | # install accessors, but locally defined methods | ||||
| 240 | # can then overwrite them. It is maybe a little odd, but | ||||
| 241 | # I think this should be the order of things. | ||||
| 242 | if (defined $attributes) { | ||||
| 243 | if(ref($attributes) eq 'ARRAY'){ | ||||
| 244 | # array of Mouse::Meta::Attribute | ||||
| 245 | foreach my $attr (@{$attributes}) { | ||||
| 246 | $meta->add_attribute($attr); | ||||
| 247 | } | ||||
| 248 | } | ||||
| 249 | else{ | ||||
| 250 | # hash map of name and attribute spec pairs | ||||
| 251 | while(my($name, $attr) = each %{$attributes}){ | ||||
| 252 | $meta->add_attribute($name => $attr); | ||||
| 253 | } | ||||
| 254 | } | ||||
| 255 | } | ||||
| 256 | if (defined $methods) { | ||||
| 257 | while(my($method_name, $method_body) = each %{$methods}){ | ||||
| 258 | $meta->add_method($method_name, $method_body); | ||||
| 259 | } | ||||
| 260 | } | ||||
| 261 | if (defined $roles and !$options{in_application_to_instance}){ | ||||
| 262 | Mouse::Util::apply_all_roles($package_name, @{$roles}); | ||||
| 263 | } | ||||
| 264 | |||||
| 265 | if($cache_key){ | ||||
| 266 | $IMMORTALS{$cache_key} = $meta; | ||||
| 267 | } | ||||
| 268 | |||||
| 269 | return $meta; | ||||
| 270 | } | ||||
| 271 | |||||
| 272 | sub DESTROY{ | ||||
| 273 | my($self) = @_; | ||||
| 274 | |||||
| 275 | return if $Mouse::Util::in_global_destruction; | ||||
| 276 | |||||
| 277 | my $serial_id = $self->{anon_serial_id}; | ||||
| 278 | return if !$serial_id; | ||||
| 279 | |||||
| 280 | # XXX: cleaning stash with threads causes panic/SEGV on legacy perls. | ||||
| 281 | if(exists $INC{'threads.pm'}) { | ||||
| 282 | # (caller)[2] indicates the caller's line number, | ||||
| 283 | # which is zero when the current thread is joining (destroying). | ||||
| 284 | return if( (caller)[2] == 0); | ||||
| 285 | } | ||||
| 286 | |||||
| 287 | # clean up mortal anonymous class stuff | ||||
| 288 | |||||
| 289 | # @ISA is a magical variable, so we must clear it manually. | ||||
| 290 | @{$self->{superclasses}} = () if exists $self->{superclasses}; | ||||
| 291 | |||||
| 292 | # Then, clear the symbol table hash | ||||
| 293 | %{$self->namespace} = (); | ||||
| 294 | |||||
| 295 | my $name = $self->name; | ||||
| 296 | delete $METAS{$name}; | ||||
| 297 | |||||
| 298 | $name =~ s/ $serial_id \z//xms; | ||||
| 299 | 3 | 68µs | 2 | 37µs | # spent 24µs (10+13) within Mouse::Meta::Module::BEGIN@299 which was called:
# once (10µs+13µs) by Mouse::BEGIN@4 at line 299 # spent 24µs making 1 call to Mouse::Meta::Module::BEGIN@299
# spent 13µs making 1 call to strict::unimport |
| 300 | delete ${$name}{ $serial_id . '::' }; | ||||
| 301 | return; | ||||
| 302 | } | ||||
| 303 | |||||
| 304 | |||||
| 305 | 1 | 9µs | 1; | ||
| 306 | __END__ | ||||
# spent 501µs within Mouse::Meta::Module::add_method which was called 65 times, avg 8µs/call:
# 49 times (379µs+0s) by Mouse::Meta::Attribute::install_accessors at line 265 of Mouse/Meta/Attribute.pm, avg 8µs/call
# 8 times (77µs+0s) by Mouse::init_meta at line 137 of Mouse.pm, avg 10µs/call
# 5 times (30µs+0s) by Mouse::Meta::Class::make_immutable at line 292 of Mouse/Meta/Class.pm, avg 6µs/call
# 3 times (16µs+0s) by Mouse::Meta::Class::make_immutable at line 298 of Mouse/Meta/Class.pm, avg 5µs/call |