← Index
NYTProf Performance Profile   « block view • line view • sub view »
For 05.Domain_and_Item.t
  Run on Tue May 4 17:21:41 2010
Reported on Tue May 4 17:22:21 2010

File /usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Moose/Meta/Attribute.pm
Statements Executed 15646
Statement Execution Time 26.5ms
Subroutines — ordered by exclusive time
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
88229.30ms29.6msMoose::Meta::Attribute::::new Moose::Meta::Attribute::new
415115.51ms75.7msMoose::Meta::Attribute::::initialize_instance_slot Moose::Meta::Attribute::initialize_instance_slot
335115.19ms57.9msMoose::Meta::Attribute::::_coerce_and_verify Moose::Meta::Attribute::_coerce_and_verify
1114.32ms43.7msMoose::Meta::Attribute::::BEGIN@18 Moose::Meta::Attribute::BEGIN@18
335113.04ms4.71msMoose::Meta::Attribute::::_set_initial_slot_value Moose::Meta::Attribute::_set_initial_slot_value
285112.67ms9.86msMoose::Meta::Attribute::::verify_against_type_constraint Moose::Meta::Attribute::verify_against_type_constraint
1111.58ms1.69msMoose::Meta::Attribute::::BEGIN@15 Moose::Meta::Attribute::BEGIN@15
110411.34ms68.6msMoose::Meta::Attribute::::_process_accessors Moose::Meta::Attribute::_process_accessors
1111.15ms1.73msMoose::Meta::Attribute::::BEGIN@17 Moose::Meta::Attribute::BEGIN@17
88331.09ms5.85msMoose::Meta::Attribute::::_process_options Moose::Meta::Attribute::_process_options
8733969µs37.4msMoose::Meta::Attribute::::interpolate_class_and_new Moose::Meta::Attribute::interpolate_class_and_new
8943817µs78.7msMoose::Meta::Attribute::::install_accessors Moose::Meta::Attribute::install_accessors
111588µs754µsMoose::Meta::Attribute::::BEGIN@16 Moose::Meta::Attribute::BEGIN@16
8921430µs7.71msMoose::Meta::Attribute::::interpolate_class Moose::Meta::Attribute::interpolate_class
8611380µs485µsMoose::Meta::Attribute::::_check_associated_methods Moose::Meta::Attribute::_check_associated_methods
1111125µs321µsMoose::Meta::Attribute::::_weaken_value Moose::Meta::Attribute::_weaken_value
10911120µs120µsMoose::Meta::Attribute::::accessor_metaclass Moose::Meta::Attribute::accessor_metaclass
881270µs70µsMoose::Meta::Attribute::::CORE:sort Moose::Meta::Attribute::CORE:sort (opcode)
11125µs94µsMoose::Meta::Attribute::::does Moose::Meta::Attribute::does
11119µs22µsMoose::Meta::Attribute::::BEGIN@4 Moose::Meta::Attribute::BEGIN@4
1119µs5.00msMoose::Meta::Attribute::::BEGIN@20 Moose::Meta::Attribute::BEGIN@20
1118µs38µsMoose::Meta::Attribute::::BEGIN@9 Moose::Meta::Attribute::BEGIN@9
1117µs17µsMoose::Meta::Attribute::::BEGIN@5 Moose::Meta::Attribute::BEGIN@5
1117µs31µsMoose::Meta::Attribute::::BEGIN@8 Moose::Meta::Attribute::BEGIN@8
1117µs38µsMoose::Meta::Attribute::::BEGIN@7 Moose::Meta::Attribute::BEGIN@7
1114µs11µsMoose::Meta::Attribute::::__ANON__[:35] Moose::Meta::Attribute::__ANON__[:35]
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__[: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::::_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::::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::::get_value Moose::Meta::Attribute::get_value
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
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
4323µs226µs
# spent 22µs (19+3) within Moose::Meta::Attribute::BEGIN@4 which was called # once (19µs+3µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 4
use strict;
# spent 22µs making 1 call to Moose::Meta::Attribute::BEGIN@4 # spent 3µs making 1 call to strict::import
5324µs226µs
# spent 17µ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 17µs making 1 call to Moose::Meta::Attribute::BEGIN@5 # spent 10µs making 1 call to warnings::import
6
7324µs268µs
# spent 38µs (7+31) within Moose::Meta::Attribute::BEGIN@7 which was called # once (7µs+31µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 7
use Scalar::Util 'blessed', 'weaken';
# spent 38µs making 1 call to Moose::Meta::Attribute::BEGIN@7 # spent 31µ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
9321µs269µs
# spent 38µs (8+31) within Moose::Meta::Attribute::BEGIN@9 which was called # once (8µs+31µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 9
use Try::Tiny;
# spent 38µs making 1 call to Moose::Meta::Attribute::BEGIN@9 # spent 31µs making 1 call to Exporter::import
10336µ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
121700nsour $VERSION = '0.98';
131300nsour $AUTHORITY = 'cpan:STEVAN';
14
153128µs11.69ms
# spent 1.69ms (1.58+113µs) within Moose::Meta::Attribute::BEGIN@15 which was called # once (1.58ms+113µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 15
use Moose::Meta::Method::Accessor;
# spent 1.69ms making 1 call to Moose::Meta::Attribute::BEGIN@15
16399µs1754µs
# spent 754µs (588+166) within Moose::Meta::Attribute::BEGIN@16 which was called # once (588µs+166µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 16
use Moose::Meta::Method::Delegation;
# spent 754µs making 1 call to Moose::Meta::Attribute::BEGIN@16
17390µs11.73ms
# spent 1.73ms (1.15+584µs) within Moose::Meta::Attribute::BEGIN@17 which was called # once (1.15ms+584µs) by Moose::Meta::TypeCoercion::BEGIN@8 at line 17
use Moose::Util ();
# spent 1.73ms making 1 call to Moose::Meta::Attribute::BEGIN@17
183112µs143.7ms
# spent 43.7ms (4.32+39.3) within Moose::Meta::Attribute::BEGIN@18 which was called # once (4.32ms+39.3ms) by Moose::Meta::TypeCoercion::BEGIN@8 at line 18
use Moose::Util::TypeConstraints ();
# spent 43.7ms making 1 call to Moose::Meta::Attribute::BEGIN@18
19
2032.74ms29.99ms
# spent 5.00ms (9µs+4.99) within Moose::Meta::Attribute::BEGIN@20 which was called # once (9µs+4.99ms) by Moose::Meta::TypeCoercion::BEGIN@8 at line 20
use base 'Class::MOP::Attribute', 'Moose::Meta::Mixin::AttributeCore';
# spent 5.00ms making 1 call to Moose::Meta::Attribute::BEGIN@20 # spent 4.99ms making 1 call to base::import
21
2218µs2516µs__PACKAGE__->meta->add_attribute('traits' => (
# spent 454µs making 1 call to Class::MOP::Mixin::HasAttributes::add_attribute # spent 62µ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 94µs (25+69) within Moose::Meta::Attribute::does which was called # once (25µs+69µs) by Moose::Meta::Attribute::interpolate_class at line 109
sub does {
32418µs my ($self, $role_name) = @_;
33
# spent 11µs (4+7) within Moose::Meta::Attribute::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Moose/Meta/Attribute.pm:35] which was called # once (4µs+7µs) by Try::Tiny::try at line 71 of Try/Tiny.pm
my $name = try {
34119µs17µs Moose::Util::resolve_metatrait_alias(Attribute => $role_name)
# spent 7µs making 1 call to Moose::Util::resolve_metatrait_alias
35 };
# spent 37µs making 1 call to Try::Tiny::try, recursion: max depth 1, time 37µs
36 return 0 if !defined($name); # failed to load class
37 return $self->Moose::Object::does($name);
# spent 32µs making 1 call to Moose::Object::does
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 29.6ms (9.30+20.3) within Moose::Meta::Attribute::new which was called 88 times, avg 337µs/call: # 87 times (9.17ms+19.5ms) by Moose::Meta::Attribute::interpolate_class_and_new at line 78, avg 330µs/call # once (132µs+808µs) by Moose::BEGIN@20 at line 20 of Moose/Meta/TypeCoercion.pm
sub new {
5130886.48ms 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 5.71ms making 85 calls to Moose::Meta::Attribute::_process_options, avg 67µs/call # spent 1.69ms making 2 calls to MooseX::AttributeHelpers::Collection::Hash::_process_options, avg 846µs/call # spent 29µs making 1 call to Class::MOP::Class::__ANON__::SERIAL::2::_process_options
53
54 delete $options{__hack_no_process_options};
55
56 my %attrs =
57 ( map { $_ => 1 }
58 grep { defined }
# spent 2.73ms making 2472 calls to Class::MOP::Mixin::AttributeCore::init_arg, avg 1µs/call
59 map { $_->init_arg() }
# spent 1.15ms making 85 calls to Class::MOP::Object::meta, avg 13µs/call # spent 1.06ms making 84 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_all_attributes, avg 13µs/call # spent 490µs making 4 calls to Class::MOP::Class::get_all_attributes, avg 123µs/call # spent 38µs making 2 calls to MooseX::AttributeHelpers::Collection::Hash::meta, avg 19µs/call # spent 9µs making 1 call to Class::MOP::Class::__ANON__::SERIAL::2::meta
60 $class->meta()->get_all_attributes()
61 );
62
63 my @bad = sort grep { ! $attrs{$_} } keys %options;
# spent 70µs making 88 calls to Moose::Meta::Attribute::CORE:sort, avg 798ns/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 7.35ms making 88 calls to Class::MOP::Attribute::new, avg 84µs/call
71}
72
73
# spent 37.4ms (969µs+36.4) within Moose::Meta::Attribute::interpolate_class_and_new which was called 87 times, avg 429µs/call: # 49 times (524µs+14.1ms) by Moose::Meta::Class::_process_new_attribute at line 607 of Moose/Meta/Class.pm, avg 298µs/call # 37 times (427µs+13.7ms) by Moose::Meta::Role::Attribute::attribute_for_class at line 67 of Moose/Meta/Role/Attribute.pm, avg 381µs/call # once (18µs+8.62ms) by MooseX::ClassAttribute::Role::Meta::Class::_process_new_class_attribute at line 106 of MooseX/ClassAttribute/Role/Meta/Class.pm
sub interpolate_class_and_new {
74261828µs my ($class, $name, %args) = @_;
75
76 my ( $new_class, @traits ) = $class->interpolate_class(\%args);
# spent 7.71ms making 87 calls to Moose::Meta::Attribute::interpolate_class, avg 89µs/call
77
78 $new_class->new($name, %args, ( scalar(@traits) ? ( traits => \@traits ) : () ) );
# spent 28.7ms making 87 calls to Moose::Meta::Attribute::new, avg 330µs/call
79}
80
81
# spent 7.71ms (430µs+7.28) within Moose::Meta::Attribute::interpolate_class which was called 89 times, avg 87µs/call: # 87 times (419µs+7.29ms) by Moose::Meta::Attribute::interpolate_class_and_new at line 76, avg 89µs/call # 2 times (12µs+-12µs) by Moose::Meta::Attribute::interpolate_class at line 89, avg 0s/call
sub interpolate_class {
82543478µ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 );
# spent 82µs making 2 calls to Moose::Util::resolve_metaclass_alias, avg 41µs/call
88
89 if ( $class ne $new_class ) {
# spent 8µs making 2 calls to UNIVERSAL::can, avg 4µs/call # spent 12µs making 2 calls to Moose::Meta::Attribute::interpolate_class, avg 6µs/call, recursion: max depth 1, time 12µs
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)
# spent 246µs making 1 call to Moose::Util::resolve_metatrait_alias
107 || $trait;
108
109 next if $class->does($trait);
# spent 94µs making 1 call to Moose::Meta::Attribute::does
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(
# spent 6.85ms making 1 call to Moose::Meta::Class::create_anon_class
120 superclasses => [ $class ],
121 roles => [ @traits ],
122 cache => 1,
123 );
124
125 $class = $anon_class->name;
# spent 900ns making 1 call to Class::MOP::Package::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 5.85ms (1.09+4.76) within Moose::Meta::Attribute::_process_options which was called 88 times, avg 66µs/call: # 85 times (1.03ms+4.67ms) by Moose::Meta::Attribute::new at line 52, avg 67µs/call # 2 times (45µs+87µs) by Class::MOP::Method::Wrapped::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Class/MOP/Method/Wrapped.pm:49] at line 48 of Class/MOP/Method/Wrapped.pm, avg 66µs/call # once (12µs+0s) by Class::MOP::Class:::around at line 30 of MooseX/ClassAttribute/Role/Meta/Attribute.pm
sub _process_options {
25912431.05ms 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')) {
# spent 40µs making 62 calls to Scalar::Util::blessed, avg 640ns/call # spent 19µs making 1 call to MooseX::Types::TypeDecorator::isa
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.70ms making 61 calls to Moose::Util::TypeConstraints::find_or_create_isa_type_constraint, avg 77µ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
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
366
# spent 75.7ms (5.51+70.2) within Moose::Meta::Attribute::initialize_instance_slot which was called 415 times, avg 182µs/call: # 415 times (5.51ms+70.2ms) by Class::MOP::Class::_construct_instance at line 364 of Class/MOP/Class.pm, avg 182µs/call
sub initialize_instance_slot {
36742283.96ms my ($self, $meta_instance, $instance, $params) = @_;
368 my $init_arg = $self->init_arg();
# spent 761µs making 415 calls to Class::MOP::Mixin::AttributeCore::init_arg, avg 2µs/call
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;
# spent 230µs making 99 calls to Moose::Meta::Mixin::AttributeCore::is_lazy, avg 2µ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 58µs making 21 calls to Moose::Meta::Mixin::AttributeCore::is_required, avg 3µ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)
386 if ($self->has_default) {
# spent 42µs making 21 calls to Class::MOP::Mixin::AttributeCore::has_default, avg 2µs/call # spent 3µs making 2 calls to Class::MOP::Mixin::AttributeCore::has_builder, avg 1µs/call
387 $val = $self->default($instance);
# spent 212µs making 19 calls to Class::MOP::Mixin::AttributeCore::default, avg 11µs/call
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 );
# spent 57.9ms making 335 calls to Moose::Meta::Attribute::_coerce_and_verify, avg 173µs/call
399
400 $self->set_initial_value($instance, $val);
# spent 10.4ms making 335 calls to Class::MOP::Attribute::set_initial_value, avg 31µs/call
401
402 if ( ref $val && $self->is_weak_ref ) {
# spent 321µs making 11 calls to Moose::Meta::Attribute::_weaken_value, avg 29µs/call # spent 270µs making 124 calls to Moose::Meta::Mixin::AttributeCore::is_weak_ref, avg 2µs/call
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
432
# spent 4.71ms (3.04+1.67) within Moose::Meta::Attribute::_set_initial_slot_value which was called 335 times, avg 14µs/call: # 335 times (3.04ms+1.67ms) by Class::MOP::Attribute::set_initial_value at line 251 of Class/MOP/Attribute.pm, avg 14µs/call
sub _set_initial_slot_value {
43310052.75ms my ($self, $meta_instance, $instance, $value) = @_;
434
435 my $slot_name = $self->name;
# spent 261µs making 335 calls to Class::MOP::Mixin::AttributeCore::name, avg 778ns/call
436
437 return $meta_instance->set_slot_value($instance, $slot_name, $value)
# spent 856µs making 335 calls to Class::MOP::Instance::set_slot_value, avg 3µs/call # spent 553µs making 335 calls to Class::MOP::Mixin::AttributeCore::has_initializer, avg 2µ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
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
486
# spent 321µs (125+195) within Moose::Meta::Attribute::_weaken_value which was called 11 times, avg 29µs/call: # 11 times (125µs+195µs) by Moose::Meta::Attribute::initialize_instance_slot at line 402, avg 29µs/call
sub _weaken_value {
48733117µs my ( $self, $instance ) = @_;
488
489 my $meta_instance = Class::MOP::Class->initialize( blessed($instance) )
# spent 71µs making 11 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance, avg 6µs/call # spent 50µs making 11 calls to Class::MOP::Class::initialize, avg 5µs/call # spent 9µs making 11 calls to Scalar::Util::blessed, avg 836ns/call
490 ->get_meta_instance;
491
492 $meta_instance->weaken_slot_value( $instance, $self->name );
# spent 58µs making 11 calls to Class::MOP::Instance::weaken_slot_value, avg 5µs/call # spent 6µs making 11 calls to Class::MOP::Mixin::AttributeCore::name, avg 555ns/call
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
540109241µs
# spent 120µs within Moose::Meta::Attribute::accessor_metaclass which was called 109 times, avg 1µs/call: # 109 times (120µ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 78.7ms (817µs+77.9) within Moose::Meta::Attribute::install_accessors which was called 89 times, avg 885µs/call: # 85 times (760µs+72.8ms) 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 865µs/call # 2 times (28µs+2.15ms) by Class::MOP::Method::Wrapped::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Class/MOP/Method/Wrapped.pm:64] at line 54 of Class/MOP/Method/Wrapped.pm, avg 1.09ms/call # once (17µs+1.92ms) by MooseX::ClassAttribute::Role::Meta::Class::add_class_attribute at line 59 of MooseX/ClassAttribute/Role/Meta/Class.pm # once (12µs+1.08ms) by Class::MOP::Class::_inline_accessors at line 1030 of Class/MOP/Class.pm
sub install_accessors {
543356716µs my $self = shift;
544 $self->SUPER::install_accessors(@_);
# spent 77.7ms making 89 calls to Class::MOP::Attribute::install_accessors, avg 873µs/call
545 $self->install_delegation if $self->has_handles;
# spent 232µs making 89 calls to Moose::Meta::Mixin::AttributeCore::has_handles, avg 3µs/call
546 return;
547}
548
549
# spent 485µs (380+106) within Moose::Meta::Attribute::_check_associated_methods which was called 86 times, avg 6µs/call: # 86 times (380µs+106µs) by Moose::Meta::Class::add_attribute at line 303 of Moose/Meta/Class.pm, avg 6µs/call
sub _check_associated_methods {
550172296µs my $self = shift;
551 unless (
# spent 106µs making 86 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 68.6ms (1.34+67.3) within Moose::Meta::Attribute::_process_accessors which was called 110 times, avg 624µs/call: # 68 times (855µs+46.4ms) by Class::MOP::Attribute::install_accessors at line 358 of Class/MOP/Attribute.pm, avg 696µs/call # 21 times (236µs+16.2ms) by Class::MOP::Attribute::install_accessors at line 354 of Class/MOP/Attribute.pm, avg 784µs/call # 18 times (210µs+3.90ms) by Class::MOP::Attribute::install_accessors at line 366 of Class/MOP/Attribute.pm, avg 228µs/call # 3 times (35µs+705µs) by Class::MOP::Attribute::install_accessors at line 370 of Class/MOP/Attribute.pm, avg 247µs/call
sub _process_accessors {
5666601.04ms 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 3.57ms making 110 calls to Class::MOP::Mixin::HasMethods::get_method, avg 32µs/call # spent 98µs making 110 calls to Class::MOP::Attribute::associated_class, avg 886ns/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 63.6ms making 110 calls to Class::MOP::Attribute::_process_accessors, avg 578µ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
732
# spent 57.9ms (5.19+52.7) within Moose::Meta::Attribute::_coerce_and_verify which was called 335 times, avg 173µs/call: # 335 times (5.19ms+52.7ms) by Moose::Meta::Attribute::initialize_instance_slot at line 398, avg 173µs/call
sub _coerce_and_verify {
73324803.40ms my $self = shift;
734 my $val = shift;
735 my $instance = shift;
736
737 return $val unless $self->has_type_constraint;
# spent 544µs making 335 calls to Moose::Meta::Mixin::AttributeCore::has_type_constraint, avg 2µs/call
738
739 my $type_constraint = $self->type_constraint;
# spent 492µs making 285 calls to Moose::Meta::Mixin::AttributeCore::type_constraint, avg 2µs/call
740 if ($self->should_coerce && $type_constraint->has_coercion) {
# spent 40.9ms making 250 calls to Moose::Meta::TypeConstraint::coerce, avg 164µs/call # spent 453µs making 285 calls to Moose::Meta::Mixin::AttributeCore::should_coerce, avg 2µs/call # spent 448µs making 250 calls to Moose::Meta::TypeConstraint::has_coercion, avg 2µs/call
741 $val = $type_constraint->coerce($val);
742 }
743
744 $self->verify_against_type_constraint($val, instance => $instance);
# spent 9.86ms making 285 calls to Moose::Meta::Attribute::verify_against_type_constraint, avg 35µs/call
745
746 return $val;
747}
748
749
# spent 9.86ms (2.67+7.19) within Moose::Meta::Attribute::verify_against_type_constraint which was called 285 times, avg 35µs/call: # 285 times (2.67ms+7.19ms) by Moose::Meta::Attribute::_coerce_and_verify at line 744, avg 35µs/call
sub verify_against_type_constraint {
75014251.76ms my $self = shift;
751 my $val = shift;
752
753 return 1 if !$self->has_type_constraint;
# spent 395µs making 285 calls to Moose::Meta::Mixin::AttributeCore::has_type_constraint, avg 1µs/call
754
755 my $type_constraint = $self->type_constraint;
# spent 411µs making 285 calls to Moose::Meta::Mixin::AttributeCore::type_constraint, avg 1µs/call
756
757 $type_constraint->check($val)
# spent 4.63ms making 258 calls to Moose::Meta::TypeConstraint::check, avg 18µs/call # spent 1.75ms making 27 calls to MooseX::Types::TypeDecorator::AUTOLOAD, avg 65µs/call
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
767111µ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 70µs within Moose::Meta::Attribute::CORE:sort which was called 88 times, avg 798ns/call: # 88 times (70µs+0s) by Moose::Meta::Attribute::new at line 63 of Moose/Meta/Attribute.pm, avg 798ns/call
sub Moose::Meta::Attribute::CORE:sort; # xsub