← Index
NYTProf Performance Profile   « block view • line view • sub view »
For /usr/bin/epoll_server.pl
  Run on Wed Jan 5 05:34:33 2011
Reported on Wed Jan 5 05:39:48 2011

File /usr/lib/perl5/vendor_perl/5.10.1/i386-linux-thread-multi/Moose/Meta/Attribute.pm
Statements Executed 11159
Statement Execution Time 127ms
Subroutines — ordered by exclusive time
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1203269.6ms223msMoose::Meta::Attribute::::new Moose::Meta::Attribute::new
11123.8ms249msMoose::Meta::Attribute::::BEGIN@18 Moose::Meta::Attribute::BEGIN@18
139418.62ms443msMoose::Meta::Attribute::::_process_accessors Moose::Meta::Attribute::_process_accessors
1117.97ms8.65msMoose::Meta::Attribute::::BEGIN@15 Moose::Meta::Attribute::BEGIN@15
153116.57ms20.8msMoose::Meta::Attribute::::initialize_instance_slot Moose::Meta::Attribute::initialize_instance_slot
118115.58ms10.5msMoose::Meta::Attribute::::_process_options Moose::Meta::Attribute::_process_options
1115.56ms9.60msMoose::Meta::Attribute::::BEGIN@17 Moose::Meta::Attribute::BEGIN@17
117225.46ms269msMoose::Meta::Attribute::::interpolate_class_and_new Moose::Meta::Attribute::interpolate_class_and_new
87114.88ms22.4msMoose::Meta::Attribute::::get_value Moose::Meta::Attribute::get_value
121214.75ms527msMoose::Meta::Attribute::::install_accessors Moose::Meta::Attribute::install_accessors
119214.39ms47.5msMoose::Meta::Attribute::::interpolate_class Moose::Meta::Attribute::interpolate_class
1113.66ms4.53msMoose::Meta::Attribute::::BEGIN@16 Moose::Meta::Attribute::BEGIN@16
119113.53ms4.28msMoose::Meta::Attribute::::_check_associated_methods Moose::Meta::Attribute::_check_associated_methods
31113.17ms10.7msMoose::Meta::Attribute::::set_value Moose::Meta::Attribute::set_value
5111.35ms15.3msMoose::Meta::Attribute::::install_delegation Moose::Meta::Attribute::install_delegation
54311.29ms9.86msMoose::Meta::Attribute::::_coerce_and_verify Moose::Meta::Attribute::_coerce_and_verify
17111.05ms4.98msMoose::Meta::Attribute::::does Moose::Meta::Attribute::does
12211935µs935µsMoose::Meta::Attribute::::accessor_metaclass Moose::Meta::Attribute::accessor_metaclass
211911µs7.33msMoose::Meta::Attribute::::clone Moose::Meta::Attribute::clone
12012894µs894µsMoose::Meta::Attribute::::CORE:sort Moose::Meta::Attribute::CORE:sort (opcode)
1411740µs6.04msMoose::Meta::Attribute::::_make_delegation_method Moose::Meta::Attribute::_make_delegation_method
2311611µs991µsMoose::Meta::Attribute::::_set_initial_slot_value Moose::Meta::Attribute::_set_initial_slot_value
1711529µs1.31msMoose::Meta::Attribute::::__ANON__[:35] Moose::Meta::Attribute::__ANON__[:35]
411226µs834µsMoose::Meta::Attribute::::_call_builder Moose::Meta::Attribute::_call_builder
211205µs8.15msMoose::Meta::Attribute::::clone_and_inherit_options Moose::Meta::Attribute::clone_and_inherit_options
511200µs7.97msMoose::Meta::Attribute::::verify_against_type_constraint Moose::Meta::Attribute::verify_against_type_constraint
511164µs206µsMoose::Meta::Attribute::::_canonicalize_handles Moose::Meta::Attribute::_canonicalize_handles
111109µs122µsMoose::Meta::Attribute::::BEGIN@4 Moose::Meta::Attribute::BEGIN@4
152286µs86µsMoose::Meta::Attribute::::CORE:match Moose::Meta::Attribute::CORE:match (opcode)
141165µs65µsMoose::Meta::Attribute::::delegation_metaclass Moose::Meta::Attribute::delegation_metaclass
21153µs1.39msMoose::Meta::Attribute::::remove_accessors Moose::Meta::Attribute::remove_accessors
11142µs32.3msMoose::Meta::Attribute::::BEGIN@20 Moose::Meta::Attribute::BEGIN@20
11133µs222µsMoose::Meta::Attribute::::BEGIN@5 Moose::Meta::Attribute::BEGIN@5
11132µs396µsMoose::Meta::Attribute::::BEGIN@7 Moose::Meta::Attribute::BEGIN@7
11132µs168µsMoose::Meta::Attribute::::BEGIN@9 Moose::Meta::Attribute::BEGIN@9
11132µs138µsMoose::Meta::Attribute::::BEGIN@8 Moose::Meta::Attribute::BEGIN@8
21120µs20µsMoose::Meta::Attribute::::legal_options_for_inheritance Moose::Meta::Attribute::legal_options_for_inheritance
11117µs17µsMoose::Meta::Attribute::::BEGIN@10 Moose::Meta::Attribute::BEGIN@10
0000s0sMoose::Meta::Attribute::Custom::Moose::::register_implementationMoose::Meta::Attribute::Custom::Moose::register_implementation
0000s0sMoose::Meta::Attribute::::__ANON__[:293] Moose::Meta::Attribute::__ANON__[:293]
0000s0sMoose::Meta::Attribute::::__ANON__[:450] Moose::Meta::Attribute::__ANON__[:450]
0000s0sMoose::Meta::Attribute::::__ANON__[:631] Moose::Meta::Attribute::__ANON__[:631]
0000s0sMoose::Meta::Attribute::::_find_delegate_metaclass Moose::Meta::Attribute::_find_delegate_metaclass
0000s0sMoose::Meta::Attribute::::_get_delegate_method_list Moose::Meta::Attribute::_get_delegate_method_list
0000s0sMoose::Meta::Attribute::::_weaken_value Moose::Meta::Attribute::_weaken_value
0000s0sMoose::Meta::Attribute::::remove_delegation Moose::Meta::Attribute::remove_delegation
0000s0sMoose::Meta::Attribute::::throw_error Moose::Meta::Attribute::throw_error
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1
2package Moose::Meta::Attribute;
3
4390µs2135µs
# spent 122µs (109+13) within Moose::Meta::Attribute::BEGIN@4 which was called # once (109µs+13µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 4
use strict;
# spent 122µs making 1 call to Moose::Meta::Attribute::BEGIN@4 # spent 13µs making 1 call to strict::import
5397µs2411µs
# spent 222µs (33+189) within Moose::Meta::Attribute::BEGIN@5 which was called # once (33µs+189µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 5
use warnings;
# spent 222µs making 1 call to Moose::Meta::Attribute::BEGIN@5 # spent 189µs making 1 call to warnings::import
6
73211µs2760µs
# spent 396µs (32+364) within Moose::Meta::Attribute::BEGIN@7 which was called # once (32µs+364µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 7
use Scalar::Util 'blessed', 'weaken';
# spent 396µs making 1 call to Moose::Meta::Attribute::BEGIN@7 # spent 364µs making 1 call to Exporter::import
8384µs2245µs
# spent 138µs (32+107) within Moose::Meta::Attribute::BEGIN@8 which was called # once (32µs+107µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 8
use List::MoreUtils 'any';
# spent 138µs making 1 call to Moose::Meta::Attribute::BEGIN@8 # spent 107µs making 1 call to Exporter::import
9386µs2304µs
# spent 168µs (32+136) within Moose::Meta::Attribute::BEGIN@9 which was called # once (32µs+136µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 9
use Try::Tiny;
# spent 168µs making 1 call to Moose::Meta::Attribute::BEGIN@9 # spent 136µs making 1 call to Exporter::import
103228µs117µs
# spent 17µs within Moose::Meta::Attribute::BEGIN@10 which was called # once (17µs+0s) by Moose::Meta::TypeCoercion::BEGIN@8 at line 10
use overload ();
# spent 17µs making 1 call to Moose::Meta::Attribute::BEGIN@10
11
1215µsour $VERSION = '1.01';
1312µsour $AUTHORITY = 'cpan:STEVAN';
14
153668µs18.65ms
# spent 8.65ms (7.97+682µs) within Moose::Meta::Attribute::BEGIN@15 which was called # once (7.97ms+682µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 15
use Moose::Meta::Method::Accessor;
# spent 8.65ms making 1 call to Moose::Meta::Attribute::BEGIN@15
163371µs14.53ms
# spent 4.53ms (3.66+873µs) within Moose::Meta::Attribute::BEGIN@16 which was called # once (3.66ms+873µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 16
use Moose::Meta::Method::Delegation;
# spent 4.53ms making 1 call to Moose::Meta::Attribute::BEGIN@16
173330µs19.60ms
# spent 9.60ms (5.56+4.04) within Moose::Meta::Attribute::BEGIN@17 which was called # once (5.56ms+4.04ms) by Moose::Meta::TypeCoercion::BEGIN@8 at line 17
use Moose::Util ();
# spent 9.60ms making 1 call to Moose::Meta::Attribute::BEGIN@17
183434µs1249ms
# spent 249ms (23.8+226) within Moose::Meta::Attribute::BEGIN@18 which was called # once (23.8ms+226ms) by Moose::Meta::TypeCoercion::BEGIN@8 at line 18
use Moose::Util::TypeConstraints ();
# spent 249ms making 1 call to Moose::Meta::Attribute::BEGIN@18
19
20314.5ms264.6ms
# spent 32.3ms (42µs+32.3) within Moose::Meta::Attribute::BEGIN@20 which was called # once (42µs+32.3ms) by Moose::Meta::TypeCoercion::BEGIN@8 at line 20
use base 'Class::MOP::Attribute', 'Moose::Meta::Mixin::AttributeCore';
# spent 32.3ms making 1 call to Moose::Meta::Attribute::BEGIN@20 # spent 32.3ms making 1 call to base::import
21
221103µs23.47ms__PACKAGE__->meta->add_attribute('traits' => (
# spent 2.81ms making 1 call to Class::MOP::Mixin::HasAttributes::add_attribute # spent 662µs making 1 call to Class::MOP::Object::meta
23 reader => 'applied_traits',
24 predicate => 'has_applied_traits',
25));
26
27# we need to have a ->does method in here to
28# more easily support traits, and the introspection
29# of those traits. We extend the does check to look
30# for metatrait aliases.
31
# spent 4.98ms (1.05+3.93) within Moose::Meta::Attribute::does which was called 17 times, avg 293µs/call: # 17 times (1.05ms+3.93ms) by Moose::Meta::Attribute::interpolate_class at line 109, avg 293µs/call
sub does {
32681.08ms my ($self, $role_name) = @_;
33
# spent 1.31ms (529µs+785µs) within Moose::Meta::Attribute::__ANON__[/usr/lib/perl5/vendor_perl/5.10.1/i386-linux-thread-multi/Moose/Meta/Attribute.pm:35] which was called 17 times, avg 77µs/call: # 17 times (529µs+785µs) by Try::Tiny::try at line 71 of Try/Tiny.pm, avg 77µs/call
my $name = try {
3417239µs17785µs Moose::Util::resolve_metatrait_alias(Attribute => $role_name)
# spent 785µs making 17 calls to Moose::Util::resolve_metatrait_alias, avg 46µs/call
35 };
# spent 2.36ms making 17 calls to Try::Tiny::try, avg 139µs/call, recursion: max depth 1, time 2.15ms
36 return 0 if !defined($name); # failed to load class
37 return $self->Moose::Object::does($name);
# spent 1.57ms making 17 calls to Moose::Object::does, avg 92µs/call
38}
39
40sub throw_error {
41 my $self = shift;
42 my $class = ( ref $self && $self->associated_class ) || "Moose::Meta::Class";
43 unshift @_, "message" if @_ % 2 == 1;
44 unshift @_, attr => $self if ref $self;
45 unshift @_, $class;
46 my $handler = $class->can("throw_error"); # to avoid incrementing depth by 1
47 goto $handler;
48}
49
50
# spent 223ms (69.6+153) within Moose::Meta::Attribute::new which was called 120 times, avg 1.86ms/call: # 117 times (68.5ms+148ms) by Moose::Meta::Attribute::interpolate_class_and_new at line 78, avg 1.85ms/call # 2 times (552µs+562µs) by Moose::Meta::Attribute::clone at line 249, avg 557µs/call # once (562µs+4.89ms) by Moose::BEGIN@20 at line 20 of Moose/Meta/TypeCoercion.pm
sub new {
5184031.4ms my ($class, $name, %options) = @_;
52 $class->_process_options($name, \%options) unless $options{__hack_no_process_options}; # used from clone()... YECHKKK FIXME ICKY YUCK GROSS
# spent 10.5ms making 118 calls to Moose::Meta::Attribute::_process_options, avg 89µs/call
53
54 delete $options{__hack_no_process_options};
55
56 my %attrs =
57 ( map { $_ => 1 }
58 grep { defined }
# spent 26.7ms making 3360 calls to Class::MOP::Mixin::AttributeCore::init_arg, avg 8µs/call
59336024.5ms24024.7ms map { $_->init_arg() }
# spent 10.8ms making 18 calls to Class::MOP::Class::get_all_attributes, avg 601µs/call # spent 7.08ms making 103 calls to Class::MOP::Object::meta, avg 69µs/call # spent 5.99ms making 102 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_all_attributes, avg 59µs/call # spent 825µs making 17 calls to Class::MOP::Class::__ANON__::SERIAL::8::meta, avg 49µs/call
60 $class->meta()->get_all_attributes()
61 );
62
63 my @bad = sort grep { ! $attrs{$_} } keys %options;
# spent 894µs making 120 calls to Moose::Meta::Attribute::CORE:sort, avg 7µs/call
64
65 if (@bad)
66 {
67 Carp::cluck "Found unknown argument(s) passed to '$name' attribute constructor in '$class': @bad";
68 }
69
70 return $class->SUPER::new($name, %options);
# spent 90.8ms making 120 calls to Class::MOP::Attribute::new, avg 756µs/call
71}
72
73
# spent 269ms (5.46+264) within Moose::Meta::Attribute::interpolate_class_and_new which was called 117 times, avg 2.30ms/call: # 105 times (4.85ms+247ms) by Moose::Meta::Class::_process_new_attribute at line 607 of Moose/Meta/Class.pm, avg 2.39ms/call # 12 times (605µs+17.4ms) by Moose::Meta::Role::Attribute::attribute_for_class at line 67 of Moose/Meta/Role/Attribute.pm, avg 1.50ms/call
sub interpolate_class_and_new {
743514.87ms my ($class, $name, %args) = @_;
75
76 my ( $new_class, @traits ) = $class->interpolate_class(\%args);
# spent 47.5ms making 117 calls to Moose::Meta::Attribute::interpolate_class, avg 406µs/call
77
78 $new_class->new($name, %args, ( scalar(@traits) ? ( traits => \@traits ) : () ) );
# spent 216ms making 117 calls to Moose::Meta::Attribute::new, avg 1.85ms/call
79}
80
81
# spent 47.5ms (4.39+43.1) within Moose::Meta::Attribute::interpolate_class which was called 119 times, avg 399µs/call: # 117 times (4.36ms+43.1ms) by Moose::Meta::Attribute::interpolate_class_and_new at line 76, avg 406µs/call # 2 times (23µs+0s) by Moose::Meta::Attribute::clone_and_inherit_options at line 218, avg 12µs/call
sub interpolate_class {
827143.34ms my ($class, $options) = @_;
83
84 $class = ref($class) || $class;
85
86 if ( my $metaclass_name = delete $options->{metaclass} ) {
87 my $new_class = Moose::Util::resolve_metaclass_alias( Attribute => $metaclass_name );
88
89 if ( $class ne $new_class ) {
90 if ( $new_class->can("interpolate_class") ) {
91 return $new_class->interpolate_class($options);
92 } else {
93 $class = $new_class;
94 }
95 }
96 }
97
98 my @traits;
99
10051268µs if (my $traits = $options->{traits}) {
101 my $i = 0;
102 while ($i < @$traits) {
103102667µs my $trait = $traits->[$i++];
104 next if ref($trait); # options to a trait we discarded
105
106 $trait = Moose::Util::resolve_metatrait_alias(Attribute => $trait)
# spent 16.3ms making 17 calls to Moose::Util::resolve_metatrait_alias, avg 959µs/call
107 || $trait;
108
109 next if $class->does($trait);
# spent 4.98ms making 17 calls to Moose::Meta::Attribute::does, avg 293µs/call
110
111 push @traits, $trait;
112
113 # are there options?
114 push @traits, $traits->[$i++]
115 if $traits->[$i] && ref($traits->[$i]);
116 }
117
11834631µs if (@traits) {
119 my $anon_class = Moose::Meta::Class->create_anon_class(
# spent 21.7ms making 17 calls to Moose::Meta::Class::create_anon_class, avg 1.28ms/call
120 superclasses => [ $class ],
121 roles => [ @traits ],
122 cache => 1,
123 );
124
125 $class = $anon_class->name;
# spent 95µs making 17 calls to Class::MOP::Package::name, avg 6µs/call
126 }
127 }
128
129 return ( wantarray ? ( $class, @traits ) : $class );
130}
131
132# ...
133
134111µsmy @legal_options_for_inheritance = qw(
135 default coerce required
136 documentation lazy handles
137 builder type_constraint
138 definition_context
139 lazy_build weak_ref
140);
141
142226µs
# spent 20µs within Moose::Meta::Attribute::legal_options_for_inheritance which was called 2 times, avg 10µs/call: # 2 times (20µs+0s) by Moose::Meta::Attribute::clone_and_inherit_options at line 172, avg 10µs/call
sub legal_options_for_inheritance { @legal_options_for_inheritance }
143
144# NOTE/TODO
145# This method *must* be able to handle
146# Class::MOP::Attribute instances as
147# well. Yes, I know that is wrong, but
148# apparently we didn't realize it was
149# doing that and now we have some code
150# which is dependent on it. The real
151# solution of course is to push this
152# feature back up into Class::MOP::Attribute
153# but I not right now, I am too lazy.
154# However if you are reading this and
155# looking for something to do,.. please
156# be my guest.
157# - stevan
158
# spent 8.15ms (205µs+7.95) within Moose::Meta::Attribute::clone_and_inherit_options which was called 2 times, avg 4.08ms/call: # 2 times (205µs+7.95ms) by Moose::Meta::Class::_process_inherited_attribute at line 615 of Moose/Meta/Class.pm, avg 4.08ms/call
sub clone_and_inherit_options {
15920144µs my ($self, %options) = @_;
160
161 my %copy = %options;
162
163 my %actual_options;
164
165 # NOTE:
166 # we may want to extends a Class::MOP::Attribute
167 # in which case we need to be able to use the
168 # core set of legal options that have always
169 # been here. But we allows Moose::Meta::Attribute
170 # instances to changes them.
171 # - SL
172 my @legal_options = $self->can('legal_options_for_inheritance')
# spent 20µs making 2 calls to Moose::Meta::Attribute::legal_options_for_inheritance, avg 10µs/call # spent 7µs making 2 calls to UNIVERSAL::can, avg 4µs/call
173 ? $self->legal_options_for_inheritance
174 : @legal_options_for_inheritance;
175
176 foreach my $legal_option (@legal_options) {
1773048µs if (exists $options{$legal_option}) {
178 $actual_options{$legal_option} = $options{$legal_option};
179 delete $options{$legal_option};
180 }
181 }
182
183 if ($options{isa}) {
184 my $type_constraint;
185 if (blessed($options{isa}) && $options{isa}->isa('Moose::Meta::TypeConstraint')) {
186 $type_constraint = $options{isa};
187 }
188 else {
189 $type_constraint = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options{isa});
190 (defined $type_constraint)
191 || $self->throw_error("Could not find the type constraint '" . $options{isa} . "'", data => $options{isa});
192 }
193
194 $actual_options{type_constraint} = $type_constraint;
195 delete $options{isa};
196 }
197
198 if ($options{does}) {
199 my $type_constraint;
200 if (blessed($options{does}) && $options{does}->isa('Moose::Meta::TypeConstraint')) {
201 $type_constraint = $options{does};
202 }
203 else {
204 $type_constraint = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options{does});
205 (defined $type_constraint)
206 || $self->throw_error("Could not find the type constraint '" . $options{does} . "'", data => $options{does});
207 }
208
209 $actual_options{type_constraint} = $type_constraint;
210 delete $options{does};
211 }
212
213 # NOTE:
214 # this doesn't apply to Class::MOP::Attributes,
215 # so we can ignore it for them.
216 # - SL
21710580µs26µs if ($self->can('interpolate_class')) {
# spent 6µs making 2 calls to UNIVERSAL::can, avg 3µs/call
218 ( $actual_options{metaclass}, my @traits ) = $self->interpolate_class(\%options);
# spent 23µs making 2 calls to Moose::Meta::Attribute::interpolate_class, avg 12µs/call
219
220 my %seen;
221 my @all_traits = grep { $seen{$_}++ } @{ $self->applied_traits || [] }, @traits;
# spent 555µs making 2 calls to Moose::Meta::Attribute::applied_traits, avg 278µs/call
222 $actual_options{traits} = \@all_traits if @all_traits;
223
224 delete @options{qw(metaclass traits)};
225 }
226
227 (scalar keys %options == 0)
228 || $self->throw_error("Illegal inherited options => (" . (join ', ' => keys %options) . ")", data => \%options);
229
230
231 $self->clone(%actual_options);
# spent 7.33ms making 2 calls to Moose::Meta::Attribute::clone, avg 3.67ms/call
232}
233
234
# spent 7.33ms (911µs+6.42) within Moose::Meta::Attribute::clone which was called 2 times, avg 3.67ms/call: # 2 times (911µs+6.42ms) by Moose::Meta::Attribute::clone_and_inherit_options at line 231, avg 3.67ms/call
sub clone {
23518209µs my ( $self, %params ) = @_;
236
237 my $class = delete $params{metaclass} || ref $self;
238
239 my ( @init, @non_init );
240
24156203µs603.70ms foreach my $attr ( grep { $_->has_value($self) } Class::MOP::class_of($self)->get_all_attributes ) {
# spent 3.61ms making 56 calls to Class::MOP::Attribute::has_value, avg 64µs/call # spent 66µs making 2 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_all_attributes, avg 33µs/call # spent 27µs making 2 calls to Class::MOP::class_of, avg 13µs/call
24222125µs2278µs push @{ $attr->has_init_arg ? \@init : \@non_init }, $attr;
# spent 78µs making 22 calls to Class::MOP::Mixin::AttributeCore::has_init_arg, avg 4µs/call
243 }
244
24522145µs441.53ms my %new_params = ( ( map { $_->init_arg => $_->get_value($self) } @init ), %params );
# spent 1.45ms making 22 calls to Class::MOP::Attribute::get_value, avg 66µs/call # spent 77µs making 22 calls to Class::MOP::Mixin::AttributeCore::init_arg, avg 4µs/call
246
247 my $name = delete $new_params{name};
248
249 my $clone = $class->new($name, %new_params, __hack_no_process_options => 1 );
# spent 1.11ms making 2 calls to Moose::Meta::Attribute::new, avg 557µs/call
250
251 foreach my $attr ( @non_init ) {
252 $attr->set_value($clone, $attr->get_value($self));
253 }
254
255 return $clone;
256}
257
258
# spent 10.5ms (5.58+4.88) within Moose::Meta::Attribute::_process_options which was called 118 times, avg 89µs/call: # 118 times (5.58ms+4.88ms) by Moose::Meta::Attribute::new at line 52, avg 89µs/call
sub _process_options {
25910624.61ms my ($class, $name, $options) = @_;
260
261100685µs if (exists $options->{is}) {
262
263 ### -------------------------
264 ## is => ro, writer => _foo # turns into (reader => foo, writer => _foo) as before
265 ## is => rw, writer => _foo # turns into (reader => foo, writer => _foo)
266 ## is => rw, accessor => _foo # turns into (accessor => _foo)
267 ## is => ro, accessor => _foo # error, accesor is rw
268 ### -------------------------
269
270115462µs if ($options->{is} eq 'ro') {
271 $class->throw_error("Cannot define an accessor name on a read-only attribute, accessors are read/write", data => $options)
272 if exists $options->{accessor};
273 $options->{reader} ||= $name;
274 }
275 elsif ($options->{is} eq 'rw') {
276 if ($options->{writer}) {
277 $options->{reader} ||= $name;
278 }
279 else {
280 $options->{accessor} ||= $name;
281 }
282 }
283 elsif ($options->{is} eq 'bare') {
284 # do nothing, but don't complain (later) about missing methods
285 }
286 else {
287 $class->throw_error("I do not understand this option (is => " . $options->{is} . ") on attribute ($name)", data => $options->{is});
288 }
289 }
290
29144501µs if (exists $options->{isa}) {
292 if (exists $options->{does}) {
293 if (try { $options->{isa}->can('does') }) {
294 ($options->{isa}->does($options->{does}))
295 || $class->throw_error("Cannot have an isa option and a does option if the isa does not do the does on attribute ($name)", data => $options);
296 }
297 else {
298 $class->throw_error("Cannot have an isa option which cannot ->does() on attribute ($name)", data => $options);
299 }
300 }
301
302 # allow for anon-subtypes here ...
30316158µs28764µs if (blessed($options->{isa}) && $options->{isa}->isa('Moose::Meta::TypeConstraint')) {
# spent 660µs making 6 calls to MooseX::Types::TypeDecorator::isa, avg 110µs/call # spent 103µs making 22 calls to Scalar::Util::blessed, avg 5µs/call
304 $options->{type_constraint} = $options->{isa};
305 }
306 else {
307 $options->{type_constraint} = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options->{isa});
# spent 4.12ms making 16 calls to Moose::Util::TypeConstraints::find_or_create_isa_type_constraint, avg 257µs/call
308 }
309 }
310 elsif (exists $options->{does}) {
311 # allow for anon-subtypes here ...
312 if (blessed($options->{does}) && $options->{does}->isa('Moose::Meta::TypeConstraint')) {
313 $options->{type_constraint} = $options->{does};
314 }
315 else {
316 $options->{type_constraint} = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options->{does});
317 }
318 }
319
320 if (exists $options->{coerce} && $options->{coerce}) {
321 (exists $options->{type_constraint})
322 || $class->throw_error("You cannot have coercion without specifying a type constraint on attribute ($name)", data => $options);
323 $class->throw_error("You cannot have a weak reference to a coerced value on attribute ($name)", data => $options)
324 if $options->{weak_ref};
325 }
326
327 if (exists $options->{trigger}) {
328 ('CODE' eq ref $options->{trigger})
329 || $class->throw_error("Trigger must be a CODE ref on attribute ($name)", data => $options->{trigger});
330 }
331
332 if (exists $options->{auto_deref} && $options->{auto_deref}) {
333 (exists $options->{type_constraint})
334 || $class->throw_error("You cannot auto-dereference without specifying a type constraint on attribute ($name)", data => $options);
335 ($options->{type_constraint}->is_a_type_of('ArrayRef') ||
336 $options->{type_constraint}->is_a_type_of('HashRef'))
337 || $class->throw_error("You cannot auto-dereference anything other than a ArrayRef or HashRef on attribute ($name)", data => $options);
338 }
339
340432µs if (exists $options->{lazy_build} && $options->{lazy_build} == 1) {
341 $class->throw_error("You can not use lazy_build and default for the same attribute ($name)", data => $options)
342 if exists $options->{default};
343 $options->{lazy} = 1;
344 $options->{builder} ||= "_build_${name}";
345210µs13µs if ($name =~ /^_/) {
# spent 3µs making 1 call to Moose::Meta::Attribute::CORE:match
346 $options->{clearer} ||= "_clear${name}";
347 $options->{predicate} ||= "_has${name}";
348 }
349 else {
350 $options->{clearer} ||= "clear_${name}";
351 $options->{predicate} ||= "has_${name}";
352 }
353 }
354
355 if (exists $options->{lazy} && $options->{lazy}) {
356 (exists $options->{default} || defined $options->{builder} )
357 || $class->throw_error("You cannot have lazy attribute ($name) without specifying a default value for it", data => $options);
358 }
359
360 if ( $options->{required} && !( ( !exists $options->{init_arg} || defined $options->{init_arg} ) || exists $options->{default} || defined $options->{builder} ) ) {
361 $class->throw_error("You cannot have a required attribute ($name) without a default, builder, or an init_arg", data => $options);
362 }
363
364}
365
366
# spent 20.8ms (6.57+14.2) within Moose::Meta::Attribute::initialize_instance_slot which was called 153 times, avg 136µs/call: # 153 times (6.57ms+14.2ms) by Class::MOP::Class::_construct_instance at line 364 of Class/MOP/Class.pm, avg 136µs/call
sub initialize_instance_slot {
3678852.90ms my ($self, $meta_instance, $instance, $params) = @_;
368 my $init_arg = $self->init_arg();
# spent 780µs making 153 calls to Class::MOP::Mixin::AttributeCore::init_arg, avg 5µs/call
369 # try to fetch the init arg from the %params ...
370
371 my $val;
372 my $value_is_set;
3732502.47ms if ( defined($init_arg) and exists $params->{$init_arg}) {
374 $val = $params->{$init_arg};
375 $value_is_set = 1;
376 }
377 else {
378 # skip it if it's lazy
379 return if $self->is_lazy;
# spent 939µs making 136 calls to Moose::Meta::Mixin::AttributeCore::is_lazy, avg 7µs/call
380 # and die if it's required and doesn't have a default value
381 $self->throw_error("Attribute (" . $self->name . ") is required", object => $instance, data => $params)
# spent 315µs making 40 calls to Moose::Meta::Mixin::AttributeCore::is_required, avg 8µs/call
382 if $self->is_required && !$self->has_default && !$self->has_builder;
383
384 # if nothing was in the %params, we can use the
385 # attribute's default value (if it has one)
3868215µs80450µs if ($self->has_default) {
# spent 261µs making 40 calls to Class::MOP::Mixin::AttributeCore::has_default, avg 7µs/call # spent 188µs making 40 calls to Class::MOP::Mixin::AttributeCore::has_builder, avg 5µs/call
387 $val = $self->default($instance);
388 $value_is_set = 1;
389 }
390 elsif ($self->has_builder) {
391 $val = $self->_call_builder($instance);
# spent 834µs making 4 calls to Moose::Meta::Attribute::_call_builder, avg 209µs/call
392 $value_is_set = 1;
393 }
394 }
395
396 return unless $value_is_set;
397
398 $val = $self->_coerce_and_verify( $val, $instance );
# spent 8.76ms making 21 calls to Moose::Meta::Attribute::_coerce_and_verify, avg 417µs/call
399
400 $self->set_initial_value($instance, $val);
# spent 2.10ms making 21 calls to Class::MOP::Attribute::set_initial_value, avg 100µs/call
401
402 if ( ref $val && $self->is_weak_ref ) {
# spent 39µs making 4 calls to Moose::Meta::Mixin::AttributeCore::is_weak_ref, avg 10µs/call
403 $self->_weaken_value($instance);
404 }
405}
406
407
# spent 834µs (226+609) within Moose::Meta::Attribute::_call_builder which was called 4 times, avg 209µs/call: # 4 times (226µs+609µs) by Moose::Meta::Attribute::initialize_instance_slot at line 391, avg 209µs/call
sub _call_builder {
40812204µs my ( $self, $instance ) = @_;
409
410 my $builder = $self->builder();
# spent 22µs making 4 calls to Class::MOP::Mixin::AttributeCore::builder, avg 6µs/call
411
412 return $instance->$builder()
# spent 546µs making 4 calls to MooseX::Role::WithOverloading::Meta::Role::Application::_build_overload_ops, avg 137µs/call # spent 21µs making 4 calls to Class::MOP::Mixin::AttributeCore::builder, avg 5µs/call # spent 19µs making 4 calls to UNIVERSAL::can, avg 5µs/call
413 if $instance->can( $self->builder );
414
415 $self->throw_error( blessed($instance)
416 . " does not support builder method '"
417 . $self->builder
418 . "' for attribute '"
419 . $self->name
420 . "'",
421 object => $instance,
422 );
423}
424
425## Slot management
426
427# FIXME:
428# this duplicates too much code from
429# Class::MOP::Attribute, we need to
430# refactor these bits eventually.
431# - SL
432
# spent 991µs (611+380) within Moose::Meta::Attribute::_set_initial_slot_value which was called 23 times, avg 43µs/call: # 23 times (611µs+380µs) by Class::MOP::Attribute::set_initial_value at line 251 of Class/MOP/Attribute.pm, avg 43µs/call
sub _set_initial_slot_value {
43369684µs my ($self, $meta_instance, $instance, $value) = @_;
434
435 my $slot_name = $self->name;
# spent 65µs making 23 calls to Class::MOP::Mixin::AttributeCore::name, avg 3µs/call
436
437 return $meta_instance->set_slot_value($instance, $slot_name, $value)
# spent 203µs making 23 calls to Class::MOP::Instance::set_slot_value, avg 9µs/call # spent 113µs making 23 calls to Class::MOP::Mixin::AttributeCore::has_initializer, avg 5µs/call
438 unless $self->has_initializer;
439
440 my ($type_constraint, $can_coerce);
441 if ($self->has_type_constraint) {
442 $type_constraint = $self->type_constraint;
443 $can_coerce = ($self->should_coerce && $type_constraint->has_coercion);
444 }
445
446 my $callback = sub {
447 my $val = $self->_coerce_and_verify( shift, $instance );;
448
449 $meta_instance->set_slot_value($instance, $slot_name, $val);
450 };
451
452 my $initializer = $self->initializer;
453
454 # most things will just want to set a value, so make it first arg
455 $instance->$initializer($value, $callback, $self);
456}
457
458
# spent 10.7ms (3.17+7.48) within Moose::Meta::Attribute::set_value which was called 31 times, avg 344µs/call: # 31 times (3.17ms+7.48ms) by Catalyst::Plugin::Session::_extended_session_expires or Catalyst::Plugin::Session::_flash or Catalyst::Plugin::Session::_flash_keep_keys or Catalyst::Plugin::Session::_flash_key_hashes or Catalyst::Plugin::Session::_session or Catalyst::Plugin::Session::_session_data_sig or Catalyst::Plugin::Session::_session_expires or Catalyst::Plugin::Session::_sessionid or Catalyst::Plugin::Session::_tried_loading_flash_data or Catalyst::Plugin::Session::_tried_loading_session_data or Catalyst::Plugin::Session::_tried_loading_session_expires or Catalyst::Plugin::Session::_tried_loading_session_id or Catalyst::View::TT::include_path at line 11 of MooseX/Emulate/Class/Accessor/Fast/Meta/Accessor.pm, avg 344µs/call
sub set_value {
4593103.44ms my ($self, $instance, @args) = @_;
460 my $value = $args[0];
461
462 my $attr_name = $self->name;
# spent 428µs making 31 calls to Class::MOP::Mixin::AttributeCore::name, avg 14µs/call
463
464 if ($self->is_required and not @args) {
# spent 323µs making 31 calls to Moose::Meta::Mixin::AttributeCore::is_required, avg 10µs/call
465 $self->throw_error("Attribute ($attr_name) is required", object => $instance);
466 }
467
468 $value = $self->_coerce_and_verify( $value, $instance );
# spent 1.05ms making 31 calls to Moose::Meta::Attribute::_coerce_and_verify, avg 34µs/call
469
470 my @old;
471 if ( $self->has_trigger && $self->has_value($instance) ) {
# spent 684µs making 31 calls to Moose::Meta::Mixin::AttributeCore::has_trigger, avg 22µs/call
472 @old = $self->get_value($instance, 'for trigger');
473 }
474
475 $self->SUPER::set_value($instance, $value);
# spent 4.74ms making 31 calls to Class::MOP::Attribute::set_value, avg 153µs/call
476
477 if ( ref $value && $self->is_weak_ref ) {
# spent 53µs making 6 calls to Moose::Meta::Mixin::AttributeCore::is_weak_ref, avg 9µs/call
478 $self->_weaken_value($instance);
479 }
480
481 if ($self->has_trigger) {
# spent 203µs making 31 calls to Moose::Meta::Mixin::AttributeCore::has_trigger, avg 7µs/call
482 $self->trigger->($instance, $value, @old);
483 }
484}
485
486sub _weaken_value {
487 my ( $self, $instance ) = @_;
488
489 my $meta_instance = Class::MOP::Class->initialize( blessed($instance) )
490 ->get_meta_instance;
491
492 $meta_instance->weaken_slot_value( $instance, $self->name );
493}
494
495
# spent 22.4ms (4.88+17.6) within Moose::Meta::Attribute::get_value which was called 87 times, avg 258µs/call: # 87 times (4.88ms+17.6ms) by Catalyst::Dispatcher::postload_dispatch_types or Catalyst::Dispatcher::preload_dispatch_types or Catalyst::Plugin::Session::_extended_session_expires or Catalyst::Plugin::Session::_flash or Catalyst::Plugin::Session::_flash_keep_keys or Catalyst::Plugin::Session::_flash_key_hashes or Catalyst::Plugin::Session::_session or Catalyst::Plugin::Session::_session_data_sig or Catalyst::Plugin::Session::_session_expires or Catalyst::Plugin::Session::_sessionid or Catalyst::Plugin::Session::_tried_loading_flash_data or Catalyst::Plugin::Session::_tried_loading_session_data or Catalyst::Plugin::Session::_tried_loading_session_expires or Catalyst::Plugin::Session::_tried_loading_session_id or Catalyst::View::TT::include_path or Catalyst::View::TT::template at line 13 of MooseX/Emulate/Class/Accessor/Fast/Meta/Accessor.pm, avg 258µs/call
sub get_value {
4962611.73ms my ($self, $instance, $for_trigger) = @_;
497
498223µs87998µs if ($self->is_lazy) {
# spent 998µs making 87 calls to Moose::Meta::Mixin::AttributeCore::is_lazy, avg 11µs/call
499860µs2214µs unless ($self->has_value($instance)) {
# spent 214µs making 2 calls to Class::MOP::Attribute::has_value, avg 107µs/call
500 my $value;
501 if ($self->has_default) {
# spent 277µs making 2 calls to Class::MOP::Mixin::AttributeCore::default, avg 139µs/call # spent 10µs making 2 calls to Class::MOP::Mixin::AttributeCore::has_default, avg 5µs/call
502 $value = $self->default($instance);
503 } elsif ( $self->has_builder ) {
504 $value = $self->_call_builder($instance);
505 }
506
507 $value = $self->_coerce_and_verify( $value, $instance );
# spent 53µs making 2 calls to Moose::Meta::Attribute::_coerce_and_verify, avg 26µs/call
508
509 $self->set_initial_value($instance, $value);
# spent 334µs making 2 calls to Class::MOP::Attribute::set_initial_value, avg 167µs/call
510 }
511 }
512
513872.26ms87695µs if ( $self->should_auto_deref && ! $for_trigger ) {
# spent 695µs making 87 calls to Moose::Meta::Mixin::AttributeCore::should_auto_deref, avg 8µs/call
514
515 my $type_constraint = $self->type_constraint;
516
517 if ($type_constraint->is_a_type_of('ArrayRef')) {
518 my $rv = $self->SUPER::get_value($instance);
519 return unless defined $rv;
520 return wantarray ? @{ $rv } : $rv;
521 }
522 elsif ($type_constraint->is_a_type_of('HashRef')) {
523 my $rv = $self->SUPER::get_value($instance);
524 return unless defined $rv;
525 return wantarray ? %{ $rv } : $rv;
526 }
527 else {
528 $self->throw_error("Can not auto de-reference the type constraint '" . $type_constraint->name . "'", object => $instance, type_constraint => $type_constraint);
529 }
530
531 }
532 else {
533
534 return $self->SUPER::get_value($instance);
# spent 15.0ms making 87 calls to Class::MOP::Attribute::get_value, avg 172µs/call
535 }
536}
537
538## installing accessors
539
5401221.43ms
# spent 935µs within Moose::Meta::Attribute::accessor_metaclass which was called 122 times, avg 8µs/call: # 122 times (935µs+0s) by Class::MOP::Attribute::__ANON__[/usr/lib/perl5/vendor_perl/5.10.1/i386-linux-thread-multi/Class/MOP/Attribute.pm:340] at line 332 of Class/MOP/Attribute.pm, avg 8µs/call
sub accessor_metaclass { 'Moose::Meta::Method::Accessor' }
541
542
# spent 527ms (4.75+522) within Moose::Meta::Attribute::install_accessors which was called 121 times, avg 4.35ms/call: # 120 times (4.71ms+514ms) by Class::MOP::Class::__ANON__[/usr/lib/perl5/vendor_perl/5.10.1/i386-linux-thread-multi/Class/MOP/Class.pm:515] at line 514 of Class/MOP/Class.pm, avg 4.32ms/call # once (44µs+7.59ms) by Class::MOP::Class::_inline_accessors at line 1030 of Class/MOP/Class.pm
sub install_accessors {
5434844.90ms my $self = shift;
544 $self->SUPER::install_accessors(@_);
# spent 505ms making 121 calls to Class::MOP::Attribute::install_accessors, avg 4.17ms/call
545 $self->install_delegation if $self->has_handles;
# spent 15.3ms making 5 calls to Moose::Meta::Attribute::install_delegation, avg 3.06ms/call # spent 1.62ms making 121 calls to Moose::Meta::Mixin::AttributeCore::has_handles, avg 13µs/call
546 return;
547}
548
549
# spent 4.28ms (3.53+749µs) within Moose::Meta::Attribute::_check_associated_methods which was called 119 times, avg 36µs/call: # 119 times (3.53ms+749µs) by Moose::Meta::Class::add_attribute at line 303 of Moose/Meta/Class.pm, avg 36µs/call
sub _check_associated_methods {
5502383.39ms my $self = shift;
551 unless (
# spent 749µs making 119 calls to Class::MOP::Attribute::associated_methods, avg 6µs/call
552 @{ $self->associated_methods }
553 || ($self->_is_metadata || '') eq 'bare'
554 ) {
555 Carp::cluck(
556 'Attribute (' . $self->name . ') of class '
557 . $self->associated_class->name
558 . ' has no associated methods'
559 . ' (did you mean to provide an "is" argument?)'
560 . "\n"
561 )
562 }
563}
564
565
# spent 443ms (8.62+434) within Moose::Meta::Attribute::_process_accessors which was called 139 times, avg 3.19ms/call: # 101 times (6.30ms+334ms) by Class::MOP::Attribute::install_accessors at line 354 of Class/MOP/Attribute.pm, avg 3.37ms/call # 20 times (1.27ms+78.7ms) by Class::MOP::Attribute::install_accessors at line 358 of Class/MOP/Attribute.pm, avg 4.00ms/call # 10 times (517µs+11.8ms) by Class::MOP::Attribute::install_accessors at line 366 of Class/MOP/Attribute.pm, avg 1.23ms/call # 8 times (534µs+9.52ms) by Class::MOP::Attribute::install_accessors at line 370 of Class/MOP/Attribute.pm, avg 1.26ms/call
sub _process_accessors {
5668347.29ms my $self = shift;
567 my ($type, $accessor, $generate_as_inline_methods) = @_;
568 $accessor = (keys %$accessor)[0] if (ref($accessor)||'') eq 'HASH';
569 my $method = $self->associated_class->get_method($accessor);
# spent 24.6ms making 139 calls to Class::MOP::Mixin::HasMethods::get_method, avg 177µs/call # spent 824µs making 139 calls to Class::MOP::Attribute::associated_class, avg 6µs/call
570 if ($method && !$method->isa('Class::MOP::Method::Accessor')
# spent 5µs making 1 call to UNIVERSAL::isa
571 && (!$self->definition_context
572 || $method->package_name eq $self->definition_context->{package})) {
573 Carp::cluck(
574 "You are overwriting a locally defined method ($accessor) with "
575 . "an accessor"
576 );
577 }
578 $self->SUPER::_process_accessors(@_);
# spent 409ms making 139 calls to Class::MOP::Attribute::_process_accessors, avg 2.94ms/call
579}
580
581
# spent 1.39ms (53µs+1.34) within Moose::Meta::Attribute::remove_accessors which was called 2 times, avg 694µs/call: # 2 times (53µs+1.34ms) by Class::MOP::Class::remove_attribute at line 530 of Class/MOP/Class.pm, avg 694µs/call
sub remove_accessors {
582851µs my $self = shift;
583 $self->SUPER::remove_accessors(@_);
# spent 1.32ms making 2 calls to Class::MOP::Attribute::remove_accessors, avg 662µs/call
584 $self->remove_delegation if $self->has_handles;
# spent 11µs making 2 calls to Moose::Meta::Mixin::AttributeCore::has_handles, avg 6µs/call
585 return;
586}
587
588
# spent 15.3ms (1.35+13.9) within Moose::Meta::Attribute::install_delegation which was called 5 times, avg 3.06ms/call: # 5 times (1.35ms+13.9ms) by Moose::Meta::Attribute::install_accessors at line 545, avg 3.06ms/call
sub install_delegation {
58920178µs my $self = shift;
590
591 # NOTE:
592 # Here we canonicalize the 'handles' option
593 # this will sort out any details and always
594 # return an hash of methods which we want
595 # to delagate to, see that method for details
596 my %handles = $self->_canonicalize_handles;
# spent 206µs making 5 calls to Moose::Meta::Attribute::_canonicalize_handles, avg 41µs/call
597
598
599 # install the delegation ...
600 my $associated_class = $self->associated_class;
# spent 30µs making 5 calls to Class::MOP::Attribute::associated_class, avg 6µs/call
601 foreach my $handle (keys %handles) {
6021121.37ms my $method_to_call = $handles{$handle};
603 my $class_name = $associated_class->name;
# spent 75µs making 14 calls to Class::MOP::Package::name, avg 5µs/call
604 my $name = "${class_name}::${handle}";
605
606 (!$associated_class->has_method($handle))
# spent 3.30ms making 14 calls to Class::MOP::Mixin::HasMethods::has_method, avg 236µs/call
607 || $self->throw_error("You cannot overwrite a locally defined method ($handle) with a delegation", method_name => $handle);
608
609 # NOTE:
610 # handles is not allowed to delegate
611 # any of these methods, as they will
612 # override the ones in your class, which
613 # is almost certainly not what you want.
614
615 # FIXME warn when $handle was explicitly specified, but not if the source is a regex or something
616 #cluck("Not delegating method '$handle' because it is a core method") and
617 next if $class_name->isa("Moose::Object") and $handle =~ /^BUILD|DEMOLISH$/ || Moose::Object->can($handle);
# spent 117µs making 14 calls to UNIVERSAL::can, avg 8µs/call # spent 83µs making 14 calls to Moose::Meta::Attribute::CORE:match, avg 6µs/call # spent 65µs making 14 calls to UNIVERSAL::isa, avg 5µs/call
618
619 my $method = $self->_make_delegation_method($handle, $method_to_call);
# spent 6.04ms making 14 calls to Moose::Meta::Attribute::_make_delegation_method, avg 431µs/call
620
621 $self->associated_class->add_method($method->name, $method);
# spent 3.78ms making 14 calls to Class::MOP::Mixin::HasMethods::add_method, avg 270µs/call # spent 80µs making 14 calls to Class::MOP::Attribute::associated_class, avg 6µs/call # spent 44µs making 14 calls to Class::MOP::Method::name, avg 3µs/call
622 $self->associate_method($method);
# spent 113µs making 14 calls to Class::MOP::Attribute::associate_method, avg 8µs/call
623 }
624}
625
626sub remove_delegation {
627 my $self = shift;
628 my %handles = $self->_canonicalize_handles;
629 my $associated_class = $self->associated_class;
630 foreach my $handle (keys %handles) {
631 next unless any { $handle eq $_ }
632 map { $_->name }
633 @{ $self->associated_methods };
634 $self->associated_class->remove_method($handle);
635 }
636}
637
638# private methods to help delegation ...
639
640
# spent 206µs (164+42) within Moose::Meta::Attribute::_canonicalize_handles which was called 5 times, avg 41µs/call: # 5 times (164µs+42µs) by Moose::Meta::Attribute::install_delegation at line 596, avg 41µs/call
sub _canonicalize_handles {
6411569µs my $self = shift;
642 my $handles = $self->handles;
# spent 42µs making 5 calls to Moose::Meta::Mixin::AttributeCore::handles, avg 8µs/call
643585µs if (my $handle_type = ref($handles)) {
644 if ($handle_type eq 'HASH') {
645 return %{$handles};
646 }
647 elsif ($handle_type eq 'ARRAY') {
648 return map { $_ => $_ } @{$handles};
649 }
650 elsif ($handle_type eq 'Regexp') {
651 ($self->has_type_constraint)
652 || $self->throw_error("Cannot delegate methods based on a Regexp without a type constraint (isa)", data => $handles);
653 return map { ($_ => $_) }
654 grep { /$handles/ } $self->_get_delegate_method_list;
655 }
656 elsif ($handle_type eq 'CODE') {
657 return $handles->($self, $self->_find_delegate_metaclass);
658 }
659 elsif (blessed($handles) && $handles->isa('Moose::Meta::TypeConstraint::DuckType')) {
660 return map { $_ => $_ } @{ $handles->methods };
661 }
662 elsif (blessed($handles) && $handles->isa('Moose::Meta::TypeConstraint::Role')) {
663 $handles = $handles->role;
664 }
665 else {
666 $self->throw_error("Unable to canonicalize the 'handles' option with $handles", data => $handles);
667 }
668 }
669
670 Class::MOP::load_class($handles);
671 my $role_meta = Class::MOP::class_of($handles);
672
673 (blessed $role_meta && $role_meta->isa('Moose::Meta::Role'))
674 || $self->throw_error("Unable to canonicalize the 'handles' option with $handles because its metaclass is not a Moose::Meta::Role", data => $handles);
675
676 return map { $_ => $_ }
677 grep { $_ ne 'meta' } (
678 $role_meta->get_method_list,
679 map { $_->name } $role_meta->get_required_method_list,
680 );
681}
682
683sub _find_delegate_metaclass {
684 my $self = shift;
685 if (my $class = $self->_isa_metadata) {
686 # we might be dealing with a non-Moose class,
687 # and need to make our own metaclass. if there's
688 # already a metaclass, it will be returned
689 return Moose::Meta::Class->initialize($class);
690 }
691 elsif (my $role = $self->_does_metadata) {
692 return Class::MOP::class_of($role);
693 }
694 else {
695 $self->throw_error("Cannot find delegate metaclass for attribute " . $self->name);
696 }
697}
698
699sub _get_delegate_method_list {
700 my $self = shift;
701 my $meta = $self->_find_delegate_metaclass;
702 if ($meta->isa('Class::MOP::Class')) {
703 return map { $_->name } # NOTE: !never! delegate &meta
704 grep { $_->package_name ne 'Moose::Object' && $_->name ne 'meta' }
705 $meta->get_all_methods;
706 }
707 elsif ($meta->isa('Moose::Meta::Role')) {
708 return $meta->get_method_list;
709 }
710 else {
711 $self->throw_error("Unable to recognize the delegate metaclass '$meta'", data => $meta);
712 }
713}
714
71514107µs
# spent 65µs within Moose::Meta::Attribute::delegation_metaclass which was called 14 times, avg 5µs/call: # 14 times (65µs+0s) by Moose::Meta::Attribute::_make_delegation_method at line 725, avg 5µs/call
sub delegation_metaclass { 'Moose::Meta::Method::Delegation' }
716
717
# spent 6.04ms (740µs+5.30) within Moose::Meta::Attribute::_make_delegation_method which was called 14 times, avg 431µs/call: # 14 times (740µs+5.30ms) by Moose::Meta::Attribute::install_delegation at line 619, avg 431µs/call
sub _make_delegation_method {
71856656µs my ( $self, $handle_name, $method_to_call ) = @_;
719
720 my @curried_arguments;
721
722 ($method_to_call, @curried_arguments) = @$method_to_call
723 if 'ARRAY' eq ref($method_to_call);
724
725 return $self->delegation_metaclass->new(
# spent 5.11ms making 14 calls to Moose::Meta::Method::Delegation::new, avg 365µs/call # spent 72µs making 14 calls to Class::MOP::Attribute::associated_class, avg 5µs/call # spent 65µs making 14 calls to Moose::Meta::Attribute::delegation_metaclass, avg 5µs/call # spent 49µs making 14 calls to Class::MOP::Package::name, avg 4µs/call
726 name => $handle_name,
727 package_name => $self->associated_class->name,
728 attribute => $self,
729 delegate_to_method => $method_to_call,
730 curried_arguments => \@curried_arguments,
731 );
732}
733
734
# spent 9.86ms (1.29+8.57) within Moose::Meta::Attribute::_coerce_and_verify which was called 54 times, avg 183µs/call: # 31 times (663µs+388µs) by Moose::Meta::Attribute::set_value at line 468, avg 34µs/call # 21 times (601µs+8.16ms) by Moose::Meta::Attribute::initialize_instance_slot at line 398, avg 417µs/call # 2 times (31µs+22µs) by Moose::Meta::Attribute::get_value at line 507, avg 26µs/call
sub _coerce_and_verify {
7352361.25ms my $self = shift;
736 my $val = shift;
737 my $instance = shift;
738
739 return $val unless $self->has_type_constraint;
# spent 520µs making 54 calls to Moose::Meta::Mixin::AttributeCore::has_type_constraint, avg 10µs/call
740
741 my $type_constraint = $self->type_constraint;
# spent 40µs making 5 calls to Moose::Meta::Mixin::AttributeCore::type_constraint, avg 8µs/call
742 if ($self->should_coerce && $type_constraint->has_coercion) {
# spent 37µs making 5 calls to Moose::Meta::Mixin::AttributeCore::should_coerce, avg 7µs/call
743 $val = $type_constraint->coerce($val);
744 }
745
746 $self->verify_against_type_constraint($val, instance => $instance);
# spent 7.97ms making 5 calls to Moose::Meta::Attribute::verify_against_type_constraint, avg 1.59ms/call
747
748 return $val;
749}
750
751
# spent 7.97ms (200µs+7.77) within Moose::Meta::Attribute::verify_against_type_constraint which was called 5 times, avg 1.59ms/call: # 5 times (200µs+7.77ms) by Moose::Meta::Attribute::_coerce_and_verify at line 746, avg 1.59ms/call
sub verify_against_type_constraint {
75225161µs my $self = shift;
753 my $val = shift;
754
755 return 1 if !$self->has_type_constraint;
# spent 24µs making 5 calls to Moose::Meta::Mixin::AttributeCore::has_type_constraint, avg 5µs/call
756
757 my $type_constraint = $self->type_constraint;
# spent 65µs making 5 calls to Moose::Meta::Mixin::AttributeCore::type_constraint, avg 13µs/call
758
759 $type_constraint->check($val)
# spent 7.65ms making 4 calls to MooseX::Types::TypeDecorator::AUTOLOAD, avg 1.91ms/call # spent 33µs making 1 call to Moose::Meta::TypeConstraint::check
760 || $self->throw_error("Attribute ("
761 . $self->name
762 . ") does not pass the type constraint because: "
763 . $type_constraint->get_message($val), data => $val, @_);
764}
765
766package Moose::Meta::Attribute::Custom::Moose;
767sub register_implementation { 'Moose::Meta::Attribute' }
768
769123µs1;
770
771__END__
772
773=pod
774
775=head1 NAME
776
777Moose::Meta::Attribute - The Moose attribute metaclass
778
779=head1 DESCRIPTION
780
781This class is a subclass of L<Class::MOP::Attribute> that provides
782additional Moose-specific functionality.
783
784To really understand this class, you will need to start with the
785L<Class::MOP::Attribute> documentation. This class can be understood
786as a set of additional features on top of the basic feature provided
787by that parent class.
788
789=head1 INHERITANCE
790
791C<Moose::Meta::Attribute> is a subclass of L<Class::MOP::Attribute>.
792
793=head1 METHODS
794
795Many of the documented below override methods in
796L<Class::MOP::Attribute> and add Moose specific features.
797
798=head2 Creation
799
800=over 4
801
802=item B<< Moose::Meta::Attribute->new(%options) >>
803
804This method overrides the L<Class::MOP::Attribute> constructor.
805
806Many of the options below are described in more detail in the
807L<Moose::Manual::Attributes> document.
808
809It adds the following options to the constructor:
810
811=over 8
812
813=item * is => 'ro', 'rw', 'bare'
814
815This provides a shorthand for specifying the C<reader>, C<writer>, or
816C<accessor> names. If the attribute is read-only ('ro') then it will
817have a C<reader> method with the same attribute as the name.
818
819If it is read-write ('rw') then it will have an C<accessor> method
820with the same name. If you provide an explicit C<writer> for a
821read-write attribute, then you will have a C<reader> with the same
822name as the attribute, and a C<writer> with the name you provided.
823
824Use 'bare' when you are deliberately not installing any methods
825(accessor, reader, etc.) associated with this attribute; otherwise,
826Moose will issue a deprecation warning when this attribute is added to a
827metaclass.
828
829=item * isa => $type
830
831This option accepts a type. The type can be a string, which should be
832a type name. If the type name is unknown, it is assumed to be a class
833name.
834
835This option can also accept a L<Moose::Meta::TypeConstraint> object.
836
837If you I<also> provide a C<does> option, then your C<isa> option must
838be a class name, and that class must do the role specified with
839C<does>.
840
841=item * does => $role
842
843This is short-hand for saying that the attribute's type must be an
844object which does the named role.
845
846=item * coerce => $bool
847
848This option is only valid for objects with a type constraint
849(C<isa>). If this is true, then coercions will be applied whenever
850this attribute is set.
851
852You can make both this and the C<weak_ref> option true.
853
854=item * trigger => $sub
855
856This option accepts a subroutine reference, which will be called after
857the attribute is set.
858
859=item * required => $bool
860
861An attribute which is required must be provided to the constructor. An
862attribute which is required can also have a C<default> or C<builder>,
863which will satisfy its required-ness.
864
865A required attribute must have a C<default>, C<builder> or a
866non-C<undef> C<init_arg>
867
868=item * lazy => $bool
869
870A lazy attribute must have a C<default> or C<builder>. When an
871attribute is lazy, the default value will not be calculated until the
872attribute is read.
873
874=item * weak_ref => $bool
875
876If this is true, the attribute's value will be stored as a weak
877reference.
878
879=item * auto_deref => $bool
880
881If this is true, then the reader will dereference the value when it is
882called. The attribute must have a type constraint which defines the
883attribute as an array or hash reference.
884
885=item * lazy_build => $bool
886
887Setting this to true makes the attribute lazy and provides a number of
888default methods.
889
890 has 'size' => (
891 is => 'ro',
892 lazy_build => 1,
893 );
894
895is equivalent to this:
896
897 has 'size' => (
898 is => 'ro',
899 lazy => 1,
900 builder => '_build_size',
901 clearer => 'clear_size',
902 predicate => 'has_size',
903 );
904
905=item * documentation
906
907An arbitrary string that can be retrieved later by calling C<<
908$attr->documentation >>.
909
910=back
911
912=item B<< $attr->clone(%options) >>
913
914This creates a new attribute based on attribute being cloned. You must
915supply a C<name> option to provide a new name for the attribute.
916
917The C<%options> can only specify options handled by
918L<Class::MOP::Attribute>.
919
920=back
921
922=head2 Value management
923
924=over 4
925
926=item B<< $attr->initialize_instance_slot($meta_instance, $instance, $params) >>
927
928This method is used internally to initialize the attribute's slot in
929the object C<$instance>.
930
931This overrides the L<Class::MOP::Attribute> method to handle lazy
932attributes, weak references, and type constraints.
933
934=item B<get_value>
935
936=item B<set_value>
937
938 eval { $point->meta->get_attribute('x')->set_value($point, 'forty-two') };
939 if($@) {
940 print "Oops: $@\n";
941 }
942
943I<Attribute (x) does not pass the type constraint (Int) with 'forty-two'>
944
945Before setting the value, a check is made on the type constraint of
946the attribute, if it has one, to see if the value passes it. If the
947value fails to pass, the set operation dies with a L</throw_error>.
948
949Any coercion to convert values is done before checking the type constraint.
950
951To check a value against a type constraint before setting it, fetch the
952attribute instance using L<Class::MOP::Class/find_attribute_by_name>,
953fetch the type_constraint from the attribute using L<Moose::Meta::Attribute/type_constraint>
954and call L<Moose::Meta::TypeConstraint/check>. See L<Moose::Cookbook::Basics::Recipe4>
955for an example.
956
957=back
958
959=head2 Attribute Accessor generation
960
961=over 4
962
963=item B<< $attr->install_accessors >>
964
965This method overrides the parent to also install delegation methods.
966
967If, after installing all methods, the attribute object has no associated
968methods, it throws an error unless C<< is => 'bare' >> was passed to the
969attribute constructor. (Trying to add an attribute that has no associated
970methods is almost always an error.)
971
972=item B<< $attr->remove_accessors >>
973
974This method overrides the parent to also remove delegation methods.
975
976=item B<< $attr->install_delegation >>
977
978This method adds its delegation methods to the attribute's associated
979class, if it has any to add.
980
981=item B<< $attr->remove_delegation >>
982
983This method remove its delegation methods from the attribute's
984associated class.
985
986=item B<< $attr->accessor_metaclass >>
987
988Returns the accessor metaclass name, which defaults to
989L<Moose::Meta::Method::Accessor>.
990
991=item B<< $attr->delegation_metaclass >>
992
993Returns the delegation metaclass name, which defaults to
994L<Moose::Meta::Method::Delegation>.
995
996=back
997
998=head2 Additional Moose features
999
1000These methods are not found in the superclass. They support features
1001provided by Moose.
1002
1003=over 4
1004
1005=item B<< $attr->does($role) >>
1006
1007This indicates whether the I<attribute itself> does the given
1008role. The role can be given as a full class name, or as a resolvable
1009trait name.
1010
1011Note that this checks the attribute itself, not its type constraint,
1012so it is checking the attribute's metaclass and any traits applied to
1013the attribute.
1014
1015=item B<< Moose::Meta::Class->interpolate_class_and_new($name, %options) >>
1016
1017This is an alternate constructor that handles the C<metaclass> and
1018C<traits> options.
1019
1020Effectively, this method is a factory that finds or creates the
1021appropriate class for the given C<metaclass> and/or C<traits>.
1022
1023Once it has the appropriate class, it will call C<< $class->new($name,
1024%options) >> on that class.
1025
1026=item B<< $attr->clone_and_inherit_options(%options) >>
1027
1028This method supports the C<has '+foo'> feature. It does various bits
1029of processing on the supplied C<%options> before ultimately calling
1030the C<clone> method.
1031
1032One of its main tasks is to make sure that the C<%options> provided
1033only includes the options returned by the
1034C<legal_options_for_inheritance> method.
1035
1036=item B<< $attr->legal_options_for_inheritance >>
1037
1038This returns a whitelist of options that can be overridden in a
1039subclass's attribute definition.
1040
1041This exists to allow a custom metaclass to change or add to the list
1042of options which can be changed.
1043
1044=item B<< $attr->type_constraint >>
1045
1046Returns the L<Moose::Meta::TypeConstraint> object for this attribute,
1047if it has one.
1048
1049=item B<< $attr->has_type_constraint >>
1050
1051Returns true if this attribute has a type constraint.
1052
1053=item B<< $attr->verify_against_type_constraint($value) >>
1054
1055Given a value, this method returns true if the value is valid for the
1056attribute's type constraint. If the value is not valid, it throws an
1057error.
1058
1059=item B<< $attr->handles >>
1060
1061This returns the value of the C<handles> option passed to the
1062constructor.
1063
1064=item B<< $attr->has_handles >>
1065
1066Returns true if this attribute performs delegation.
1067
1068=item B<< $attr->is_weak_ref >>
1069
1070Returns true if this attribute stores its value as a weak reference.
1071
1072=item B<< $attr->is_required >>
1073
1074Returns true if this attribute is required to have a value.
1075
1076=item B<< $attr->is_lazy >>
1077
1078Returns true if this attribute is lazy.
1079
1080=item B<< $attr->is_lazy_build >>
1081
1082Returns true if the C<lazy_build> option was true when passed to the
1083constructor.
1084
1085=item B<< $attr->should_coerce >>
1086
1087Returns true if the C<coerce> option passed to the constructor was
1088true.
1089
1090=item B<< $attr->should_auto_deref >>
1091
1092Returns true if the C<auto_deref> option passed to the constructor was
1093true.
1094
1095=item B<< $attr->trigger >>
1096
1097This is the subroutine reference that was in the C<trigger> option
1098passed to the constructor, if any.
1099
1100=item B<< $attr->has_trigger >>
1101
1102Returns true if this attribute has a trigger set.
1103
1104=item B<< $attr->documentation >>
1105
1106Returns the value that was in the C<documentation> option passed to
1107the constructor, if any.
1108
1109=item B<< $attr->has_documentation >>
1110
1111Returns true if this attribute has any documentation.
1112
1113=item B<< $attr->applied_traits >>
1114
1115This returns an array reference of all the traits which were applied
1116to this attribute. If none were applied, this returns C<undef>.
1117
1118=item B<< $attr->has_applied_traits >>
1119
1120Returns true if this attribute has any traits applied.
1121
1122=back
1123
1124=head1 BUGS
1125
1126See L<Moose/BUGS> for details on reporting bugs.
1127
1128=head1 AUTHOR
1129
1130Stevan Little E<lt>stevan@iinteractive.comE<gt>
1131
1132Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
1133
1134=head1 COPYRIGHT AND LICENSE
1135
1136Copyright 2006-2010 by Infinity Interactive, Inc.
1137
1138L<http://www.iinteractive.com>
1139
1140This library is free software; you can redistribute it and/or modify
1141it under the same terms as Perl itself.
1142
1143=cut
# spent 86µs within Moose::Meta::Attribute::CORE:match which was called 15 times, avg 6µs/call: # 14 times (83µs+0s) by Moose::Meta::Attribute::install_delegation at line 617 of Moose/Meta/Attribute.pm, avg 6µs/call # once (3µs+0s) by Moose::Meta::Attribute::_process_options at line 345 of Moose/Meta/Attribute.pm
sub Moose::Meta::Attribute::CORE:match; # xsub
# spent 894µs within Moose::Meta::Attribute::CORE:sort which was called 120 times, avg 7µs/call: # 120 times (894µs+0s) by Moose::Meta::Attribute::new at line 63 of Moose/Meta/Attribute.pm, avg 7µs/call
sub Moose::Meta::Attribute::CORE:sort; # xsub