← Index
NYTProf Performance Profile   « block view • line view • sub view »
For 01.HTTP.t
  Run on Tue May 4 15:25:55 2010
Reported on Tue May 4 15:26:06 2010

File /usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Moose/Meta/Attribute.pm
Statements Executed 380
Statement Execution Time 5.30ms
Subroutines — ordered by exclusive time
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1115.56ms41.3msMoose::Meta::Attribute::::BEGIN@18 Moose::Meta::Attribute::BEGIN@18
1111.55ms1.66msMoose::Meta::Attribute::::BEGIN@15 Moose::Meta::Attribute::BEGIN@15
1111.50ms1.71msMoose::Meta::Attribute::::BEGIN@16 Moose::Meta::Attribute::BEGIN@16
1111.14ms1.71msMoose::Meta::Attribute::::BEGIN@17 Moose::Meta::Attribute::BEGIN@17
522636µs2.13msMoose::Meta::Attribute::::new Moose::Meta::Attribute::new
61196µs4.80msMoose::Meta::Attribute::::_process_accessors Moose::Meta::Attribute::_process_accessors
62173µs5.53msMoose::Meta::Attribute::::install_accessors Moose::Meta::Attribute::install_accessors
41156µs1.28msMoose::Meta::Attribute::::interpolate_class_and_new Moose::Meta::Attribute::interpolate_class_and_new
51140µs40µsMoose::Meta::Attribute::::_process_options Moose::Meta::Attribute::_process_options
41121µs21µsMoose::Meta::Attribute::::interpolate_class Moose::Meta::Attribute::interpolate_class
41120µs26µsMoose::Meta::Attribute::::_check_associated_methods Moose::Meta::Attribute::_check_associated_methods
11115µs18µsMoose::Meta::Attribute::::BEGIN@4 Moose::Meta::Attribute::BEGIN@4
1119µs4.98msMoose::Meta::Attribute::::BEGIN@20 Moose::Meta::Attribute::BEGIN@20
5129µs9µsMoose::Meta::Attribute::::CORE:sort Moose::Meta::Attribute::CORE:sort (opcode)
6118µs8µsMoose::Meta::Attribute::::accessor_metaclass Moose::Meta::Attribute::accessor_metaclass
1117µs37µsMoose::Meta::Attribute::::BEGIN@9 Moose::Meta::Attribute::BEGIN@9
1117µs31µsMoose::Meta::Attribute::::BEGIN@8 Moose::Meta::Attribute::BEGIN@8
1117µs36µsMoose::Meta::Attribute::::BEGIN@7 Moose::Meta::Attribute::BEGIN@7
1117µs16µsMoose::Meta::Attribute::::BEGIN@5 Moose::Meta::Attribute::BEGIN@5
1114µs4µ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__[:35] Moose::Meta::Attribute::__ANON__[:35]
0000s0sMoose::Meta::Attribute::::__ANON__[:450] Moose::Meta::Attribute::__ANON__[:450]
0000s0sMoose::Meta::Attribute::::__ANON__[:631] Moose::Meta::Attribute::__ANON__[:631]
0000s0sMoose::Meta::Attribute::::_call_builder Moose::Meta::Attribute::_call_builder
0000s0sMoose::Meta::Attribute::::_canonicalize_handles Moose::Meta::Attribute::_canonicalize_handles
0000s0sMoose::Meta::Attribute::::_coerce_and_verify Moose::Meta::Attribute::_coerce_and_verify
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::::_make_delegation_method Moose::Meta::Attribute::_make_delegation_method
0000s0sMoose::Meta::Attribute::::_set_initial_slot_value Moose::Meta::Attribute::_set_initial_slot_value
0000s0sMoose::Meta::Attribute::::_weaken_value Moose::Meta::Attribute::_weaken_value
0000s0sMoose::Meta::Attribute::::clone Moose::Meta::Attribute::clone
0000s0sMoose::Meta::Attribute::::clone_and_inherit_options Moose::Meta::Attribute::clone_and_inherit_options
0000s0sMoose::Meta::Attribute::::delegation_metaclass Moose::Meta::Attribute::delegation_metaclass
0000s0sMoose::Meta::Attribute::::does Moose::Meta::Attribute::does
0000s0sMoose::Meta::Attribute::::get_value Moose::Meta::Attribute::get_value
0000s0sMoose::Meta::Attribute::::initialize_instance_slot Moose::Meta::Attribute::initialize_instance_slot
0000s0sMoose::Meta::Attribute::::install_delegation Moose::Meta::Attribute::install_delegation
0000s0sMoose::Meta::Attribute::::legal_options_for_inheritance Moose::Meta::Attribute::legal_options_for_inheritance
0000s0sMoose::Meta::Attribute::::remove_accessors Moose::Meta::Attribute::remove_accessors
0000s0sMoose::Meta::Attribute::::remove_delegation Moose::Meta::Attribute::remove_delegation
0000s0sMoose::Meta::Attribute::::set_value Moose::Meta::Attribute::set_value
0000s0sMoose::Meta::Attribute::::throw_error Moose::Meta::Attribute::throw_error
0000s0sMoose::Meta::Attribute::::verify_against_type_constraint Moose::Meta::Attribute::verify_against_type_constraint
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
4321µs220µs
# spent 18µs (15+3) within Moose::Meta::Attribute::BEGIN@4 which was called # once (15µs+3µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 4
use strict;
# spent 18µs making 1 call to Moose::Meta::Attribute::BEGIN@4 # spent 3µs making 1 call to strict::import
5323µs224µs
# spent 16µs (7+9) within Moose::Meta::Attribute::BEGIN@5 which was called # once (7µs+9µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 5
use warnings;
# spent 16µs making 1 call to Moose::Meta::Attribute::BEGIN@5 # spent 8µs making 1 call to warnings::import
6
7323µs264µs
# spent 36µs (7+28) within Moose::Meta::Attribute::BEGIN@7 which was called # once (7µs+28µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 7
use Scalar::Util 'blessed', 'weaken';
# spent 36µs making 1 call to Moose::Meta::Attribute::BEGIN@7 # spent 28µs making 1 call to Exporter::import
8322µs255µs
# spent 31µs (7+24) within Moose::Meta::Attribute::BEGIN@8 which was called # once (7µs+24µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 8
use List::MoreUtils 'any';
# spent 31µs making 1 call to Moose::Meta::Attribute::BEGIN@8 # spent 24µs making 1 call to Exporter::import
9320µs266µs
# spent 37µs (7+30) within Moose::Meta::Attribute::BEGIN@9 which was called # once (7µs+30µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 9
use Try::Tiny;
# spent 37µs making 1 call to Moose::Meta::Attribute::BEGIN@9 # spent 30µs making 1 call to Exporter::import
10348µs14µs
# spent 4µs within Moose::Meta::Attribute::BEGIN@10 which was called # once (4µs+0s) by Moose::Meta::TypeCoercion::BEGIN@8 at line 10
use overload ();
# spent 4µs making 1 call to Moose::Meta::Attribute::BEGIN@10
11
121800nsour $VERSION = '0.98';
131400nsour $AUTHORITY = 'cpan:STEVAN';
14
153116µs11.66ms
# spent 1.66ms (1.55+112µs) within Moose::Meta::Attribute::BEGIN@15 which was called # once (1.55ms+112µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 15
use Moose::Meta::Method::Accessor;
# spent 1.66ms making 1 call to Moose::Meta::Attribute::BEGIN@15
163756µs11.71ms
# spent 1.71ms (1.50+215µs) within Moose::Meta::Attribute::BEGIN@16 which was called # once (1.50ms+215µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 16
use Moose::Meta::Method::Delegation;
# spent 1.71ms making 1 call to Moose::Meta::Attribute::BEGIN@16
17391µs11.71ms
# spent 1.71ms (1.14+566µs) within Moose::Meta::Attribute::BEGIN@17 which was called # once (1.14ms+566µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 17
use Moose::Util ();
# spent 1.71ms making 1 call to Moose::Meta::Attribute::BEGIN@17
183681µs141.3ms
# spent 41.3ms (5.56+35.8) within Moose::Meta::Attribute::BEGIN@18 which was called # once (5.56ms+35.8ms) by Moose::Meta::TypeCoercion::BEGIN@8 at line 18
use Moose::Util::TypeConstraints ();
# spent 41.3ms making 1 call to Moose::Meta::Attribute::BEGIN@18
19
2032.73ms29.95ms
# spent 4.98ms (9µs+4.97) within Moose::Meta::Attribute::BEGIN@20 which was called # once (9µs+4.97ms) by Moose::Meta::TypeCoercion::BEGIN@8 at line 20
use base 'Class::MOP::Attribute', 'Moose::Meta::Mixin::AttributeCore';
# spent 4.98ms making 1 call to Moose::Meta::Attribute::BEGIN@20 # spent 4.97ms making 1 call to base::import
21
2218µs2528µs__PACKAGE__->meta->add_attribute('traits' => (
# spent 471µs making 1 call to Class::MOP::Mixin::HasAttributes::add_attribute # spent 58µ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.
31sub does {
32 my ($self, $role_name) = @_;
33 my $name = try {
34 Moose::Util::resolve_metatrait_alias(Attribute => $role_name)
35 };
36 return 0 if !defined($name); # failed to load class
37 return $self->Moose::Object::does($name);
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 2.13ms (636µs+1.49) within Moose::Meta::Attribute::new which was called 5 times, avg 426µs/call: # 4 times (514µs+689µs) by Moose::Meta::Attribute::interpolate_class_and_new at line 78, avg 301µs/call # once (122µs+805µs) by Moose::BEGIN@20 at line 20 of Moose/Meta/TypeCoercion.pm
sub new {
51175459µs 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 40µs making 5 calls to Moose::Meta::Attribute::_process_options, avg 8µs/call
53
54 delete $options{__hack_no_process_options};
55
56 my %attrs =
57 ( map { $_ => 1 }
58 grep { defined }
# spent 174µs making 140 calls to Class::MOP::Mixin::AttributeCore::init_arg, avg 1µs/call
59 map { $_->init_arg() }
# spent 239µs making 4 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_all_attributes, avg 60µs/call # spent 92µs making 1 call to Class::MOP::Class::get_all_attributes # spent 78µs making 5 calls to Class::MOP::Object::meta, avg 16µs/call
60 $class->meta()->get_all_attributes()
61 );
62
63 my @bad = sort grep { ! $attrs{$_} } keys %options;
# spent 9µs making 5 calls to Moose::Meta::Attribute::CORE:sort, avg 2µ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 863µs making 5 calls to Class::MOP::Attribute::new, avg 173µs/call
71}
72
73
# spent 1.28ms (56µs+1.22) within Moose::Meta::Attribute::interpolate_class_and_new which was called 4 times, avg 320µs/call: # 4 times (56µs+1.22ms) by Moose::Meta::Class::_process_new_attribute at line 607 of Moose/Meta/Class.pm, avg 320µs/call
sub interpolate_class_and_new {
741241µs my ($class, $name, %args) = @_;
75
76 my ( $new_class, @traits ) = $class->interpolate_class(\%args);
# spent 21µs making 4 calls to Moose::Meta::Attribute::interpolate_class, avg 5µs/call
77
78 $new_class->new($name, %args, ( scalar(@traits) ? ( traits => \@traits ) : () ) );
# spent 1.20ms making 4 calls to Moose::Meta::Attribute::new, avg 301µs/call
79}
80
81
# spent 21µs within Moose::Meta::Attribute::interpolate_class which was called 4 times, avg 5µs/call: # 4 times (21µs+0s) by Moose::Meta::Attribute::interpolate_class_and_new at line 76, avg 5µs/call
sub interpolate_class {
822429µs 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
100 if (my $traits = $options->{traits}) {
101 my $i = 0;
102 while ($i < @$traits) {
103 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)
107 || $trait;
108
109 next if $class->does($trait);
110
111 push @traits, $trait;
112
113 # are there options?
114 push @traits, $traits->[$i++]
115 if $traits->[$i] && ref($traits->[$i]);
116 }
117
118 if (@traits) {
119 my $anon_class = Moose::Meta::Class->create_anon_class(
120 superclasses => [ $class ],
121 roles => [ @traits ],
122 cache => 1,
123 );
124
125 $class = $anon_class->name;
126 }
127 }
128
129 return ( wantarray ? ( $class, @traits ) : $class );
130}
131
132# ...
133
13412µ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
142sub 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
158sub clone_and_inherit_options {
159 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')
173 ? $self->legal_options_for_inheritance
174 : @legal_options_for_inheritance;
175
176 foreach my $legal_option (@legal_options) {
177 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
217 if ($self->can('interpolate_class')) {
218 ( $actual_options{metaclass}, my @traits ) = $self->interpolate_class(\%options);
219
220 my %seen;
221 my @all_traits = grep { $seen{$_}++ } @{ $self->applied_traits || [] }, @traits;
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);
232}
233
234sub clone {
235 my ( $self, %params ) = @_;
236
237 my $class = delete $params{metaclass} || ref $self;
238
239 my ( @init, @non_init );
240
241 foreach my $attr ( grep { $_->has_value($self) } Class::MOP::class_of($self)->get_all_attributes ) {
242 push @{ $attr->has_init_arg ? \@init : \@non_init }, $attr;
243 }
244
245 my %new_params = ( ( map { $_->init_arg => $_->get_value($self) } @init ), %params );
246
247 my $name = delete $new_params{name};
248
249 my $clone = $class->new($name, %new_params, __hack_no_process_options => 1 );
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 40µs within Moose::Meta::Attribute::_process_options which was called 5 times, avg 8µs/call: # 5 times (40µs+0s) by Moose::Meta::Attribute::new at line 52, avg 8µs/call
sub _process_options {
2595742µs my ($class, $name, $options) = @_;
260
261 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
270 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
291 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 ...
303 if (blessed($options->{isa}) && $options->{isa}->isa('Moose::Meta::TypeConstraint')) {
304 $options->{type_constraint} = $options->{isa};
305 }
306 else {
307 $options->{type_constraint} = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options->{isa});
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
340 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}";
345 if ($name =~ /^_/) {
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
366sub initialize_instance_slot {
367 my ($self, $meta_instance, $instance, $params) = @_;
368 my $init_arg = $self->init_arg();
369 # try to fetch the init arg from the %params ...
370
371 my $val;
372 my $value_is_set;
373 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;
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)
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)
386 if ($self->has_default) {
387 $val = $self->default($instance);
388 $value_is_set = 1;
389 }
390 elsif ($self->has_builder) {
391 $val = $self->_call_builder($instance);
392 $value_is_set = 1;
393 }
394 }
395
396 return unless $value_is_set;
397
398 $val = $self->_coerce_and_verify( $val, $instance );
399
400 $self->set_initial_value($instance, $val);
401
402 if ( ref $val && $self->is_weak_ref ) {
403 $self->_weaken_value($instance);
404 }
405}
406
407sub _call_builder {
408 my ( $self, $instance ) = @_;
409
410 my $builder = $self->builder();
411
412 return $instance->$builder()
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
432sub _set_initial_slot_value {
433 my ($self, $meta_instance, $instance, $value) = @_;
434
435 my $slot_name = $self->name;
436
437 return $meta_instance->set_slot_value($instance, $slot_name, $value)
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
458sub set_value {
459 my ($self, $instance, @args) = @_;
460 my $value = $args[0];
461
462 my $attr_name = $self->name;
463
464 if ($self->is_required and not @args) {
465 $self->throw_error("Attribute ($attr_name) is required", object => $instance);
466 }
467
468 $value = $self->_coerce_and_verify( $value, $instance );
469
470 my @old;
471 if ( $self->has_trigger && $self->has_value($instance) ) {
472 @old = $self->get_value($instance, 'for trigger');
473 }
474
475 $self->SUPER::set_value($instance, $value);
476
477 if ( ref $value && $self->is_weak_ref ) {
478 $self->_weaken_value($instance);
479 }
480
481 if ($self->has_trigger) {
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
495sub get_value {
496 my ($self, $instance, $for_trigger) = @_;
497
498 if ($self->is_lazy) {
499 unless ($self->has_value($instance)) {
500 my $value;
501 if ($self->has_default) {
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 );
508
509 $self->set_initial_value($instance, $value);
510 }
511 }
512
513 if ( $self->should_auto_deref && ! $for_trigger ) {
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);
535 }
536}
537
538## installing accessors
539
540617µs
# spent 8µs within Moose::Meta::Attribute::accessor_metaclass which was called 6 times, avg 1µs/call: # 6 times (8µs+0s) by Class::MOP::Attribute::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Class/MOP/Attribute.pm:340] at line 332 of Class/MOP/Attribute.pm, avg 1µs/call
sub accessor_metaclass { 'Moose::Meta::Method::Accessor' }
541
542
# spent 5.53ms (73µs+5.46) within Moose::Meta::Attribute::install_accessors which was called 6 times, avg 922µs/call: # 5 times (60µs+4.38ms) by Class::MOP::Class::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Class/MOP/Class.pm:515] at line 514 of Class/MOP/Class.pm, avg 888µs/call # once (13µs+1.08ms) by Class::MOP::Class::_inline_accessors at line 1030 of Class/MOP/Class.pm
sub install_accessors {
5432464µs my $self = shift;
544 $self->SUPER::install_accessors(@_);
# spent 5.38ms making 6 calls to Class::MOP::Attribute::install_accessors, avg 897µs/call
545 $self->install_delegation if $self->has_handles;
# spent 73µs making 6 calls to Moose::Meta::Mixin::AttributeCore::has_handles, avg 12µs/call
546 return;
547}
548
549
# spent 26µs (20+5) within Moose::Meta::Attribute::_check_associated_methods which was called 4 times, avg 6µs/call: # 4 times (20µs+5µs) by Moose::Meta::Class::add_attribute at line 303 of Moose/Meta/Class.pm, avg 6µs/call
sub _check_associated_methods {
550817µs my $self = shift;
551 unless (
# spent 5µs making 4 calls to Class::MOP::Attribute::associated_methods, avg 1µ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 4.80ms (96µs+4.71) within Moose::Meta::Attribute::_process_accessors which was called 6 times, avg 801µs/call: # 6 times (96µs+4.71ms) by Class::MOP::Attribute::install_accessors at line 358 of Class/MOP/Attribute.pm, avg 801µs/call
sub _process_accessors {
5663674µs 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 237µs making 6 calls to Class::MOP::Mixin::HasMethods::get_method, avg 39µs/call # spent 5µs making 6 calls to Class::MOP::Attribute::associated_class, avg 900ns/call
570 if ($method && !$method->isa('Class::MOP::Method::Accessor')
# spent 1µ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 4.46ms making 6 calls to Class::MOP::Attribute::_process_accessors, avg 744µs/call
579}
580
581sub remove_accessors {
582 my $self = shift;
583 $self->SUPER::remove_accessors(@_);
584 $self->remove_delegation if $self->has_handles;
585 return;
586}
587
588sub install_delegation {
589 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;
597
598
599 # install the delegation ...
600 my $associated_class = $self->associated_class;
601 foreach my $handle (keys %handles) {
602 my $method_to_call = $handles{$handle};
603 my $class_name = $associated_class->name;
604 my $name = "${class_name}::${handle}";
605
606 (!$associated_class->has_method($handle))
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);
618
619 my $method = $self->_make_delegation_method($handle, $method_to_call);
620
621 $self->associated_class->add_method($method->name, $method);
622 $self->associate_method($method);
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
640sub _canonicalize_handles {
641 my $self = shift;
642 my $handles = $self->handles;
643 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 else {
663 $self->throw_error("Unable to canonicalize the 'handles' option with $handles", data => $handles);
664 }
665 }
666 else {
667 Class::MOP::load_class($handles);
668 my $role_meta = Class::MOP::class_of($handles);
669
670 (blessed $role_meta && $role_meta->isa('Moose::Meta::Role'))
671 || $self->throw_error("Unable to canonicalize the 'handles' option with $handles because its metaclass is not a Moose::Meta::Role", data => $handles);
672
673 return map { $_ => $_ }
674 grep { $_ ne 'meta' } (
675 $role_meta->get_method_list,
676 map { $_->name } $role_meta->get_required_method_list,
677 );
678 }
679}
680
681sub _find_delegate_metaclass {
682 my $self = shift;
683 if (my $class = $self->_isa_metadata) {
684 # we might be dealing with a non-Moose class,
685 # and need to make our own metaclass. if there's
686 # already a metaclass, it will be returned
687 return Moose::Meta::Class->initialize($class);
688 }
689 elsif (my $role = $self->_does_metadata) {
690 return Class::MOP::class_of($role);
691 }
692 else {
693 $self->throw_error("Cannot find delegate metaclass for attribute " . $self->name);
694 }
695}
696
697sub _get_delegate_method_list {
698 my $self = shift;
699 my $meta = $self->_find_delegate_metaclass;
700 if ($meta->isa('Class::MOP::Class')) {
701 return map { $_->name } # NOTE: !never! delegate &meta
702 grep { $_->package_name ne 'Moose::Object' && $_->name ne 'meta' }
703 $meta->get_all_methods;
704 }
705 elsif ($meta->isa('Moose::Meta::Role')) {
706 return $meta->get_method_list;
707 }
708 else {
709 $self->throw_error("Unable to recognize the delegate metaclass '$meta'", data => $meta);
710 }
711}
712
713sub delegation_metaclass { 'Moose::Meta::Method::Delegation' }
714
715sub _make_delegation_method {
716 my ( $self, $handle_name, $method_to_call ) = @_;
717
718 my @curried_arguments;
719
720 ($method_to_call, @curried_arguments) = @$method_to_call
721 if 'ARRAY' eq ref($method_to_call);
722
723 return $self->delegation_metaclass->new(
724 name => $handle_name,
725 package_name => $self->associated_class->name,
726 attribute => $self,
727 delegate_to_method => $method_to_call,
728 curried_arguments => \@curried_arguments,
729 );
730}
731
732sub _coerce_and_verify {
733 my $self = shift;
734 my $val = shift;
735 my $instance = shift;
736
737 return $val unless $self->has_type_constraint;
738
739 my $type_constraint = $self->type_constraint;
740 if ($self->should_coerce && $type_constraint->has_coercion) {
741 $val = $type_constraint->coerce($val);
742 }
743
744 $self->verify_against_type_constraint($val, instance => $instance);
745
746 return $val;
747}
748
749sub verify_against_type_constraint {
750 my $self = shift;
751 my $val = shift;
752
753 return 1 if !$self->has_type_constraint;
754
755 my $type_constraint = $self->type_constraint;
756
757 $type_constraint->check($val)
758 || $self->throw_error("Attribute ("
759 . $self->name
760 . ") does not pass the type constraint because: "
761 . $type_constraint->get_message($val), data => $val, @_);
762}
763
764package Moose::Meta::Attribute::Custom::Moose;
765sub register_implementation { 'Moose::Meta::Attribute' }
766
767110µs1;
768
769__END__
770
771=pod
772
773=head1 NAME
774
775Moose::Meta::Attribute - The Moose attribute metaclass
776
777=head1 DESCRIPTION
778
779This class is a subclass of L<Class::MOP::Attribute> that provides
780additional Moose-specific functionality.
781
782To really understand this class, you will need to start with the
783L<Class::MOP::Attribute> documentation. This class can be understood
784as a set of additional features on top of the basic feature provided
785by that parent class.
786
787=head1 INHERITANCE
788
789C<Moose::Meta::Attribute> is a subclass of L<Class::MOP::Attribute>.
790
791=head1 METHODS
792
793Many of the documented below override methods in
794L<Class::MOP::Attribute> and add Moose specific features.
795
796=head2 Creation
797
798=over 4
799
800=item B<< Moose::Meta::Attribute->new(%options) >>
801
802This method overrides the L<Class::MOP::Attribute> constructor.
803
804Many of the options below are described in more detail in the
805L<Moose::Manual::Attributes> document.
806
807It adds the following options to the constructor:
808
809=over 8
810
811=item * is => 'ro', 'rw', 'bare'
812
813This provides a shorthand for specifying the C<reader>, C<writer>, or
814C<accessor> names. If the attribute is read-only ('ro') then it will
815have a C<reader> method with the same attribute as the name.
816
817If it is read-write ('rw') then it will have an C<accessor> method
818with the same name. If you provide an explicit C<writer> for a
819read-write attribute, then you will have a C<reader> with the same
820name as the attribute, and a C<writer> with the name you provided.
821
822Use 'bare' when you are deliberately not installing any methods
823(accessor, reader, etc.) associated with this attribute; otherwise,
824Moose will issue a deprecation warning when this attribute is added to a
825metaclass.
826
827=item * isa => $type
828
829This option accepts a type. The type can be a string, which should be
830a type name. If the type name is unknown, it is assumed to be a class
831name.
832
833This option can also accept a L<Moose::Meta::TypeConstraint> object.
834
835If you I<also> provide a C<does> option, then your C<isa> option must
836be a class name, and that class must do the role specified with
837C<does>.
838
839=item * does => $role
840
841This is short-hand for saying that the attribute's type must be an
842object which does the named role.
843
844=item * coerce => $bool
845
846This option is only valid for objects with a type constraint
847(C<isa>). If this is true, then coercions will be applied whenever
848this attribute is set.
849
850You can make both this and the C<weak_ref> option true.
851
852=item * trigger => $sub
853
854This option accepts a subroutine reference, which will be called after
855the attribute is set.
856
857=item * required => $bool
858
859An attribute which is required must be provided to the constructor. An
860attribute which is required can also have a C<default> or C<builder>,
861which will satisfy its required-ness.
862
863A required attribute must have a C<default>, C<builder> or a
864non-C<undef> C<init_arg>
865
866=item * lazy => $bool
867
868A lazy attribute must have a C<default> or C<builder>. When an
869attribute is lazy, the default value will not be calculated until the
870attribute is read.
871
872=item * weak_ref => $bool
873
874If this is true, the attribute's value will be stored as a weak
875reference.
876
877=item * auto_deref => $bool
878
879If this is true, then the reader will dereference the value when it is
880called. The attribute must have a type constraint which defines the
881attribute as an array or hash reference.
882
883=item * lazy_build => $bool
884
885Setting this to true makes the attribute lazy and provides a number of
886default methods.
887
888 has 'size' => (
889 is => 'ro',
890 lazy_build => 1,
891 );
892
893is equivalent to this:
894
895 has 'size' => (
896 is => 'ro',
897 lazy => 1,
898 builder => '_build_size',
899 clearer => 'clear_size',
900 predicate => 'has_size',
901 );
902
903=item * documentation
904
905An arbitrary string that can be retrieved later by calling C<<
906$attr->documentation >>.
907
908=back
909
910=item B<< $attr->clone(%options) >>
911
912This creates a new attribute based on attribute being cloned. You must
913supply a C<name> option to provide a new name for the attribute.
914
915The C<%options> can only specify options handled by
916L<Class::MOP::Attribute>.
917
918=back
919
920=head2 Value management
921
922=over 4
923
924=item B<< $attr->initialize_instance_slot($meta_instance, $instance, $params) >>
925
926This method is used internally to initialize the attribute's slot in
927the object C<$instance>.
928
929This overrides the L<Class::MOP::Attribute> method to handle lazy
930attributes, weak references, and type constraints.
931
932=item B<get_value>
933
934=item B<set_value>
935
936 eval { $point->meta->get_attribute('x')->set_value($point, 'forty-two') };
937 if($@) {
938 print "Oops: $@\n";
939 }
940
941I<Attribute (x) does not pass the type constraint (Int) with 'forty-two'>
942
943Before setting the value, a check is made on the type constraint of
944the attribute, if it has one, to see if the value passes it. If the
945value fails to pass, the set operation dies with a L<throw_error>.
946
947Any coercion to convert values is done before checking the type constraint.
948
949To check a value against a type constraint before setting it, fetch the
950attribute instance using L<Class::MOP::Class/find_attribute_by_name>,
951fetch the type_constraint from the attribute using L<Moose::Meta::Attribute/type_constraint>
952and call L<Moose::Meta::TypeConstraint/check>. See L<Moose::Cookbook::Basics::Recipe4>
953for an example.
954
955=back
956
957=head2 Attribute Accessor generation
958
959=over 4
960
961=item B<< $attr->install_accessors >>
962
963This method overrides the parent to also install delegation methods.
964
965If, after installing all methods, the attribute object has no associated
966methods, it throws an error unless C<< is => 'bare' >> was passed to the
967attribute constructor. (Trying to add an attribute that has no associated
968methods is almost always an error.)
969
970=item B<< $attr->remove_accessors >>
971
972This method overrides the parent to also remove delegation methods.
973
974=item B<< $attr->install_delegation >>
975
976This method adds its delegation methods to the attribute's associated
977class, if it has any to add.
978
979=item B<< $attr->remove_delegation >>
980
981This method remove its delegation methods from the attribute's
982associated class.
983
984=item B<< $attr->accessor_metaclass >>
985
986Returns the accessor metaclass name, which defaults to
987L<Moose::Meta::Method::Accessor>.
988
989=item B<< $attr->delegation_metaclass >>
990
991Returns the delegation metaclass name, which defaults to
992L<Moose::Meta::Method::Delegation>.
993
994=back
995
996=head2 Additional Moose features
997
998These methods are not found in the superclass. They support features
999provided by Moose.
1000
1001=over 4
1002
1003=item B<< $attr->does($role) >>
1004
1005This indicates whether the I<attribute itself> does the given
1006role. The role can be given as a full class name, or as a resolvable
1007trait name.
1008
1009Note that this checks the attribute itself, not its type constraint,
1010so it is checking the attribute's metaclass and any traits applied to
1011the attribute.
1012
1013=item B<< Moose::Meta::Class->interpolate_class_and_new($name, %options) >>
1014
1015This is an alternate constructor that handles the C<metaclass> and
1016C<traits> options.
1017
1018Effectively, this method is a factory that finds or creates the
1019appropriate class for the given C<metaclass> and/or C<traits>.
1020
1021Once it has the appropriate class, it will call C<< $class->new($name,
1022%options) >> on that class.
1023
1024=item B<< $attr->clone_and_inherit_options(%options) >>
1025
1026This method supports the C<has '+foo'> feature. It does various bits
1027of processing on the supplied C<%options> before ultimately calling
1028the C<clone> method.
1029
1030One of its main tasks is to make sure that the C<%options> provided
1031only includes the options returned by the
1032C<legal_options_for_inheritance> method.
1033
1034=item B<< $attr->legal_options_for_inheritance >>
1035
1036This returns a whitelist of options that can be overridden in a
1037subclass's attribute definition.
1038
1039This exists to allow a custom metaclass to change or add to the list
1040of options which can be changed.
1041
1042=item B<< $attr->type_constraint >>
1043
1044Returns the L<Moose::Meta::TypeConstraint> object for this attribute,
1045if it has one.
1046
1047=item B<< $attr->has_type_constraint >>
1048
1049Returns true if this attribute has a type constraint.
1050
1051=item B<< $attr->verify_against_type_constraint($value) >>
1052
1053Given a value, this method returns true if the value is valid for the
1054attribute's type constraint. If the value is not valid, it throws an
1055error.
1056
1057=item B<< $attr->handles >>
1058
1059This returns the value of the C<handles> option passed to the
1060constructor.
1061
1062=item B<< $attr->has_handles >>
1063
1064Returns true if this attribute performs delegation.
1065
1066=item B<< $attr->is_weak_ref >>
1067
1068Returns true if this attribute stores its value as a weak reference.
1069
1070=item B<< $attr->is_required >>
1071
1072Returns true if this attribute is required to have a value.
1073
1074=item B<< $attr->is_lazy >>
1075
1076Returns true if this attribute is lazy.
1077
1078=item B<< $attr->is_lazy_build >>
1079
1080Returns true if the C<lazy_build> option was true when passed to the
1081constructor.
1082
1083=item B<< $attr->should_coerce >>
1084
1085Returns true if the C<coerce> option passed to the constructor was
1086true.
1087
1088=item B<< $attr->should_auto_deref >>
1089
1090Returns true if the C<auto_deref> option passed to the constructor was
1091true.
1092
1093=item B<< $attr->trigger >>
1094
1095This is the subroutine reference that was in the C<trigger> option
1096passed to the constructor, if any.
1097
1098=item B<< $attr->has_trigger >>
1099
1100Returns true if this attribute has a trigger set.
1101
1102=item B<< $attr->documentation >>
1103
1104Returns the value that was in the C<documentation> option passed to
1105the constructor, if any.
1106
1107=item B<< $attr->has_documentation >>
1108
1109Returns true if this attribute has any documentation.
1110
1111=item B<< $attr->applied_traits >>
1112
1113This returns an array reference of all the traits which were applied
1114to this attribute. If none were applied, this returns C<undef>.
1115
1116=item B<< $attr->has_applied_traits >>
1117
1118Returns true if this attribute has any traits applied.
1119
1120=back
1121
1122=head1 BUGS
1123
1124See L<Moose/BUGS> for details on reporting bugs.
1125
1126=head1 AUTHOR
1127
1128Stevan Little E<lt>stevan@iinteractive.comE<gt>
1129
1130Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
1131
1132=head1 COPYRIGHT AND LICENSE
1133
1134Copyright 2006-2010 by Infinity Interactive, Inc.
1135
1136L<http://www.iinteractive.com>
1137
1138This library is free software; you can redistribute it and/or modify
1139it under the same terms as Perl itself.
1140
1141=cut
# spent 9µs within Moose::Meta::Attribute::CORE:sort which was called 5 times, avg 2µs/call: # 5 times (9µs+0s) by Moose::Meta::Attribute::new at line 63 of Moose/Meta/Attribute.pm, avg 2µs/call
sub Moose::Meta::Attribute::CORE:sort; # xsub