← Index
NYTProf Performance Profile   « block view • line view • sub view »
For xt/tapper-mcp-scheduler-with-db-longrun.t
  Run on Tue May 22 17:18:39 2012
Reported on Tue May 22 17:22:34 2012

Filename/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/x86_64-linux/Class/MOP/Attribute.pm
StatementsExecuted 14621 statements in 37.0ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
254525.91ms66.3msClass::MOP::Attribute::::_process_accessorsClass::MOP::Attribute::_process_accessors
207324.90ms90.2msClass::MOP::Attribute::::install_accessorsClass::MOP::Attribute::install_accessors
403223.30ms12.3msClass::MOP::Attribute::::_inline_instance_setClass::MOP::Attribute::_inline_instance_set
376213.21ms5.07msClass::MOP::Attribute::::_set_initial_slot_valueClass::MOP::Attribute::_set_initial_slot_value
197113.01ms53.2msClass::MOP::Attribute::::__ANON__[:398]Class::MOP::Attribute::__ANON__[:398]
448112.45ms8.84msClass::MOP::Attribute::::initialize_instance_slotClass::MOP::Attribute::initialize_instance_slot
254212.32ms2.78msClass::MOP::Attribute::::_accessor_descriptionClass::MOP::Attribute::_accessor_description
1315041.83ms4.18msClass::MOP::Attribute::::newClass::MOP::Attribute::new
402531.21ms13.5msClass::MOP::Attribute::::_inline_set_valueClass::MOP::Attribute::_inline_set_value
123111.19ms1.84msClass::MOP::Attribute::::_newClass::MOP::Attribute::_new
442111.05ms1.31msClass::MOP::Attribute::::slotsClass::MOP::Attribute::slots
13111884µs1.19msClass::MOP::Attribute::::attach_to_classClass::MOP::Attribute::attach_to_class
8422783µs3.62msClass::MOP::Attribute::::_inline_instance_getClass::MOP::Attribute::_inline_instance_get
25421572µs572µsClass::MOP::Attribute::::associate_methodClass::MOP::Attribute::associate_method
24521291µs291µsClass::MOP::Attribute::::accessor_metaclassClass::MOP::Attribute::accessor_metaclass
7521268µs3.45msClass::MOP::Attribute::::_inline_get_valueClass::MOP::Attribute::_inline_get_value
1722181µs348µsClass::MOP::Attribute::::_inline_instance_hasClass::MOP::Attribute::_inline_instance_has
1211126µs307µsClass::MOP::Attribute::::get_raw_valueClass::MOP::Attribute::get_raw_value
1211115µs274µsClass::MOP::Attribute::::has_valueClass::MOP::Attribute::has_value
161166µs392µsClass::MOP::Attribute::::_inline_has_valueClass::MOP::Attribute::_inline_has_value
41141µs138µsClass::MOP::Attribute::::set_initial_valueClass::MOP::Attribute::set_initial_value
121133µs339µsClass::MOP::Attribute::::get_valueClass::MOP::Attribute::get_value
11110µs10µsClass::MOP::Attribute::::BEGIN@3Class::MOP::Attribute::BEGIN@3
1119µs15µsClass::MOP::Attribute::::BEGIN@10Class::MOP::Attribute::BEGIN@10
1119µs30µsClass::MOP::Attribute::::BEGIN@11Class::MOP::Attribute::BEGIN@11
1118µs54µsClass::MOP::Attribute::::BEGIN@15Class::MOP::Attribute::BEGIN@15
1118µs132µsClass::MOP::Attribute::::BEGIN@19Class::MOP::Attribute::BEGIN@19
1118µs35µsClass::MOP::Attribute::::BEGIN@16Class::MOP::Attribute::BEGIN@16
1117µs39µsClass::MOP::Attribute::::BEGIN@17Class::MOP::Attribute::BEGIN@17
1115µs5µsClass::MOP::Attribute::::BEGIN@13Class::MOP::Attribute::BEGIN@13
0000s0sClass::MOP::Attribute::::__ANON__[:169]Class::MOP::Attribute::__ANON__[:169]
0000s0sClass::MOP::Attribute::::__ANON__[:198]Class::MOP::Attribute::__ANON__[:198]
0000s0sClass::MOP::Attribute::::__ANON__[:218]Class::MOP::Attribute::__ANON__[:218]
0000s0sClass::MOP::Attribute::::__ANON__[:401]Class::MOP::Attribute::__ANON__[:401]
0000s0sClass::MOP::Attribute::::__ANON__[:456]Class::MOP::Attribute::__ANON__[:456]
0000s0sClass::MOP::Attribute::::_inline_clear_valueClass::MOP::Attribute::_inline_clear_value
0000s0sClass::MOP::Attribute::::_inline_instance_clearClass::MOP::Attribute::_inline_instance_clear
0000s0sClass::MOP::Attribute::::_make_initializer_writer_callbackClass::MOP::Attribute::_make_initializer_writer_callback
0000s0sClass::MOP::Attribute::::clear_valueClass::MOP::Attribute::clear_value
0000s0sClass::MOP::Attribute::::detach_from_classClass::MOP::Attribute::detach_from_class
0000s0sClass::MOP::Attribute::::get_read_methodClass::MOP::Attribute::get_read_method
0000s0sClass::MOP::Attribute::::get_read_method_refClass::MOP::Attribute::get_read_method_ref
0000s0sClass::MOP::Attribute::::get_write_methodClass::MOP::Attribute::get_write_method
0000s0sClass::MOP::Attribute::::get_write_method_refClass::MOP::Attribute::get_write_method_ref
0000s0sClass::MOP::Attribute::::remove_accessorsClass::MOP::Attribute::remove_accessors
0000s0sClass::MOP::Attribute::::set_raw_valueClass::MOP::Attribute::set_raw_value
0000s0sClass::MOP::Attribute::::set_valueClass::MOP::Attribute::set_value
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1
2package Class::MOP::Attribute;
3
# spent 10µs within Class::MOP::Attribute::BEGIN@3 which was called: # once (10µs+0s) by Class::MOP::BEGIN@27 at line 5
BEGIN {
414µs $Class::MOP::Attribute::AUTHORITY = 'cpan:STEVAN';
5123µs110µs}
# spent 10µs making 1 call to Class::MOP::Attribute::BEGIN@3
6{
722µs $Class::MOP::Attribute::VERSION = '2.0602';
8}
9
10320µs222µs
# spent 15µs (9+6) within Class::MOP::Attribute::BEGIN@10 which was called: # once (9µs+6µs) by Class::MOP::BEGIN@27 at line 10
use strict;
# spent 15µs making 1 call to Class::MOP::Attribute::BEGIN@10 # spent 6µs making 1 call to strict::import
11320µs251µs
# spent 30µs (9+21) within Class::MOP::Attribute::BEGIN@11 which was called: # once (9µs+21µs) by Class::MOP::BEGIN@27 at line 11
use warnings;
# spent 30µs making 1 call to Class::MOP::Attribute::BEGIN@11 # spent 21µs making 1 call to warnings::import
12
13320µs15µs
# spent 5µs within Class::MOP::Attribute::BEGIN@13 which was called: # once (5µs+0s) by Class::MOP::BEGIN@27 at line 13
use Class::MOP::Method::Accessor;
# spent 5µs making 1 call to Class::MOP::Attribute::BEGIN@13
14
15322µs2101µs
# spent 54µs (8+46) within Class::MOP::Attribute::BEGIN@15 which was called: # once (8µs+46µs) by Class::MOP::BEGIN@27 at line 15
use Carp 'confess';
# spent 54µs making 1 call to Class::MOP::Attribute::BEGIN@15 # spent 46µs making 1 call to Exporter::import
16318µs263µs
# spent 35µs (8+28) within Class::MOP::Attribute::BEGIN@16 which was called: # once (8µs+28µs) by Class::MOP::BEGIN@27 at line 16
use Scalar::Util 'blessed', 'weaken';
# spent 35µs making 1 call to Class::MOP::Attribute::BEGIN@16 # spent 28µs making 1 call to Exporter::import
17320µs272µs
# spent 39µs (7+32) within Class::MOP::Attribute::BEGIN@17 which was called: # once (7µs+32µs) by Class::MOP::BEGIN@27 at line 17
use Try::Tiny;
# spent 39µs making 1 call to Class::MOP::Attribute::BEGIN@17 # spent 32µs making 1 call to Exporter::import
18
1931.90ms2257µs
# spent 132µs (8+124) within Class::MOP::Attribute::BEGIN@19 which was called: # once (8µs+124µs) by Class::MOP::BEGIN@27 at line 19
use base 'Class::MOP::Object', 'Class::MOP::Mixin::AttributeCore';
# spent 132µs making 1 call to Class::MOP::Attribute::BEGIN@19 # spent 124µs making 1 call to base::import
20
21# NOTE: (meta-circularity)
22# This method will be replaced in the
23# boostrap section of Class::MOP, by
24# a new version which uses the
25# &Class::MOP::Class::construct_instance
26# method to build an attribute meta-object
27# which itself is described with attribute
28# meta-objects.
29# - Ain't meta-circularity grand? :)
30
# spent 4.18ms (1.83+2.35) within Class::MOP::Attribute::new which was called 131 times, avg 32µs/call: # 74 times (1.07ms+813µs) by Class::MOP::Mixin::HasAttributes::add_attribute at line 20 of Class/MOP/Mixin/HasAttributes.pm, avg 25µs/call # 9 times (247µs+1.08ms) by Moose::Meta::Attribute::new at line 106 of Moose/Meta/Attribute.pm, avg 148µs/call # once (29µs+24µs) by Moose::Exporter::BEGIN@13 at line 133 of Class/MOP.pm # once (16µs+13µs) by Moose::Exporter::BEGIN@13 at line 479 of Class/MOP.pm # once (14µs+13µs) by Moose::Exporter::BEGIN@13 at line 178 of Class/MOP.pm # once (13µs+13µs) by Moose::Exporter::BEGIN@13 at line 449 of Class/MOP.pm # once (14µs+11µs) by Moose::Exporter::BEGIN@13 at line 597 of Class/MOP.pm # once (13µs+12µs) by Moose::Exporter::BEGIN@13 at line 287 of Class/MOP.pm # once (12µs+12µs) by Moose::Exporter::BEGIN@13 at line 417 of Class/MOP.pm # once (11µs+13µs) by Moose::Exporter::BEGIN@13 at line 137 of Class/MOP.pm # once (10µs+13µs) by Moose::Exporter::BEGIN@13 at line 460 of Class/MOP.pm # once (13µs+10µs) by Moose::Exporter::BEGIN@13 at line 250 of Class/MOP.pm # once (9µs+14µs) by Moose::Exporter::BEGIN@13 at line 370 of Class/MOP.pm # once (13µs+9µs) by Moose::Exporter::BEGIN@13 at line 223 of Class/MOP.pm # once (9µs+13µs) by Moose::Exporter::BEGIN@13 at line 378 of Class/MOP.pm # once (9µs+12µs) by Moose::Exporter::BEGIN@13 at line 433 of Class/MOP.pm # once (9µs+12µs) by Moose::Exporter::BEGIN@13 at line 401 of Class/MOP.pm # once (9µs+12µs) by Moose::Exporter::BEGIN@13 at line 425 of Class/MOP.pm # once (9µs+12µs) by Moose::Exporter::BEGIN@13 at line 386 of Class/MOP.pm # once (9µs+12µs) by Moose::Exporter::BEGIN@13 at line 394 of Class/MOP.pm # once (12µs+9µs) by Moose::Exporter::BEGIN@13 at line 270 of Class/MOP.pm # once (9µs+12µs) by Moose::Exporter::BEGIN@13 at line 409 of Class/MOP.pm # once (9µs+12µs) by Moose::Exporter::BEGIN@13 at line 441 of Class/MOP.pm # once (14µs+6µs) by Moose::Exporter::BEGIN@13 at line 635 of Class/MOP.pm # once (13µs+7µs) by Moose::Exporter::BEGIN@13 at line 518 of Class/MOP.pm # once (9µs+10µs) by Moose::Exporter::BEGIN@13 at line 490 of Class/MOP.pm # once (10µs+9µs) by Moose::Exporter::BEGIN@13 at line 307 of Class/MOP.pm # once (10µs+8µs) by Moose::Exporter::BEGIN@13 at line 572 of Class/MOP.pm # once (10µs+7µs) by Moose::Exporter::BEGIN@13 at line 543 of Class/MOP.pm # once (11µs+7µs) by Moose::BEGIN@28 at line 47 of Moose/Meta/Class.pm # once (10µs+8µs) by Moose::Exporter::BEGIN@13 at line 534 of Class/MOP.pm # once (10µs+7µs) by Moose::Exporter::BEGIN@13 at line 291 of Class/MOP.pm # once (10µs+7µs) by Moose::Exporter::BEGIN@13 at line 150 of Class/MOP.pm # once (10µs+7µs) by Moose::Exporter::BEGIN@13 at line 355 of Class/MOP.pm # once (10µs+7µs) by Moose::Exporter::BEGIN@13 at line 198 of Class/MOP.pm # once (9µs+8µs) by Moose::Exporter::BEGIN@13 at line 551 of Class/MOP.pm # once (9µs+7µs) by Moose::Exporter::BEGIN@13 at line 562 of Class/MOP.pm # once (9µs+7µs) by Moose::Exporter::BEGIN@13 at line 182 of Class/MOP.pm # once (9µs+7µs) by Moose::Exporter::BEGIN@13 at line 618 of Class/MOP.pm # once (9µs+7µs) by Moose::Exporter::BEGIN@13 at line 317 of Class/MOP.pm # once (9µs+7µs) by Moose::Exporter::BEGIN@13 at line 327 of Class/MOP.pm # once (9µs+7µs) by Moose::Exporter::BEGIN@13 at line 649 of Class/MOP.pm # once (9µs+7µs) by Moose::Exporter::BEGIN@13 at line 601 of Class/MOP.pm # once (9µs+6µs) by Moose::Exporter::BEGIN@13 at line 581 of Class/MOP.pm # once (9µs+6µs) by Moose::Exporter::BEGIN@13 at line 504 of Class/MOP.pm # once (9µs+7µs) by Moose::Exporter::BEGIN@13 at line 511 of Class/MOP.pm # once (9µs+6µs) by Moose::Exporter::BEGIN@13 at line 625 of Class/MOP.pm # once (8µs+7µs) by Moose::Exporter::BEGIN@13 at line 497 of Class/MOP.pm # once (9µs+6µs) by Moose::Exporter::BEGIN@13 at line 338 of Class/MOP.pm # once (8µs+6µs) by Moose::Exporter::BEGIN@13 at line 642 of Class/MOP.pm
sub new {
3113101.80ms my ( $class, @args ) = @_;
32
33 unshift @args, "name" if @args % 2 == 1;
34 my %options = @args;
35
36 my $name = $options{name};
37
38 (defined $name)
39 || confess "You must provide a name for the attribute";
40
41 $options{init_arg} = $name
42 if not exists $options{init_arg};
43 if(exists $options{builder}){
44 confess("builder must be a defined scalar value which is a method name")
45 if ref $options{builder} || !(defined $options{builder});
46 confess("Setting both default and builder is not allowed.")
47 if exists $options{default};
48 } else {
4932112µs ($class->is_default_a_coderef(\%options))
# spent 112µs making 32 calls to Class::MOP::Mixin::AttributeCore::is_default_a_coderef, avg 4µs/call
50 || confess("References are not allowed as default values, you must ".
51 "wrap the default of '$name' in a CODE reference (ex: sub { [] } and not [])")
52 if exists $options{default} && ref $options{default};
53 }
54 if( $options{required} and not( defined($options{builder}) || defined($options{init_arg}) || exists $options{default} ) ) {
55 confess("A required attribute must have either 'init_arg', 'builder', or 'default'");
56 }
57
581312.24ms $class->_new(\%options);
# spent 1.84ms making 123 calls to Class::MOP::Attribute::_new, avg 15µs/call # spent 402µs making 8 calls to Moose::Meta::Attribute::_new, avg 50µs/call
59}
60
61
# spent 1.84ms (1.19+648µs) within Class::MOP::Attribute::_new which was called 123 times, avg 15µs/call: # 123 times (1.19ms+648µs) by Class::MOP::Attribute::new at line 58, avg 15µs/call
sub _new {
624901.30ms my $class = shift;
63
642648µs return Class::MOP::Class->initialize($class)->new_object(@_)
# spent 643µs making 1 call to Class::MOP::Class::new_object # spent 5µs making 1 call to Class::MOP::Class::initialize
65 if $class ne __PACKAGE__;
66
67 my $options = @_ == 1 ? $_[0] : {@_};
68
69 bless {
70 'name' => $options->{name},
71 'accessor' => $options->{accessor},
72 'reader' => $options->{reader},
73 'writer' => $options->{writer},
74 'predicate' => $options->{predicate},
75 'clearer' => $options->{clearer},
76 'builder' => $options->{builder},
77 'init_arg' => $options->{init_arg},
78 exists $options->{default}
79 ? ('default' => $options->{default})
80 : (),
81 'initializer' => $options->{initializer},
82 'definition_context' => $options->{definition_context},
83 # keep a weakened link to the
84 # class we are associated with
85 'associated_class' => undef,
86 # and a list of the methods
87 # associated with this attr
88 'associated_methods' => [],
89 # this let's us keep track of
90 # our order inside the associated
91 # class
92 'insertion_order' => undef,
93 }, $class;
94}
95
96# NOTE:
97# this is a primative (and kludgy) clone operation
98# for now, it will be replaced in the Class::MOP
99# bootstrap with a proper one, however we know
100# that this one will work fine for now.
101sub clone {
102 my $self = shift;
103 my %options = @_;
104 (blessed($self))
105 || confess "Can only clone an instance";
106 return bless { %{$self}, %options } => ref($self);
107}
108
109
# spent 8.84ms (2.45+6.39) within Class::MOP::Attribute::initialize_instance_slot which was called 448 times, avg 20µs/call: # 448 times (2.45ms+6.39ms) by Class::MOP::Class::_construct_instance at line 525 of Class/MOP/Class.pm, avg 20µs/call
sub initialize_instance_slot {
11013442.28ms my ($self, $meta_instance, $instance, $params) = @_;
111 my $init_arg = $self->{'init_arg'};
112
113 # try to fetch the init arg from the %params ...
114
115 # if nothing was in the %params, we can use the
116 # attribute's default value (if it has one)
1175006.39ms if(defined $init_arg and exists $params->{$init_arg}){
# spent 5.01ms making 372 calls to Class::MOP::Attribute::_set_initial_slot_value, avg 13µs/call # spent 1.38ms making 128 calls to Class::MOP::Mixin::AttributeCore::default, avg 11µs/call
118 $self->_set_initial_slot_value(
119 $meta_instance,
120 $instance,
121 $params->{$init_arg},
122 );
123 }
124 elsif (exists $self->{'default'}) {
125 $self->_set_initial_slot_value(
126 $meta_instance,
127 $instance,
128 $self->default($instance),
129 );
130 }
131 elsif (defined( my $builder = $self->{'builder'})) {
132 if ($builder = $instance->can($builder)) {
133 $self->_set_initial_slot_value(
134 $meta_instance,
135 $instance,
136 $instance->$builder,
137 );
138 }
139 else {
140 confess(ref($instance)." does not support builder method '". $self->{'builder'} ."' for attribute '" . $self->name . "'");
141 }
142 }
143}
144
145
# spent 5.07ms (3.21+1.86) within Class::MOP::Attribute::_set_initial_slot_value which was called 376 times, avg 13µs/call: # 372 times (3.17ms+1.84ms) by Class::MOP::Attribute::initialize_instance_slot at line 117, avg 13µs/call # 4 times (40µs+20µs) by Class::MOP::Attribute::set_initial_value at line 261, avg 15µs/call
sub _set_initial_slot_value {
14611283.09ms my ($self, $meta_instance, $instance, $value) = @_;
147
148376277µs my $slot_name = $self->name;
# spent 277µs making 376 calls to Class::MOP::Mixin::AttributeCore::name, avg 738ns/call
149
1507521.58ms return $meta_instance->set_slot_value($instance, $slot_name, $value)
# spent 998µs making 376 calls to Class::MOP::Instance::set_slot_value, avg 3µs/call # spent 584µs making 376 calls to Class::MOP::Mixin::AttributeCore::has_initializer, avg 2µs/call
151 unless $self->has_initializer;
152
153 my $callback = $self->_make_initializer_writer_callback(
154 $meta_instance, $instance, $slot_name
155 );
156
157 my $initializer = $self->initializer;
158
159 # most things will just want to set a value, so make it first arg
160 $instance->$initializer($value, $callback, $self);
161}
162
163sub _make_initializer_writer_callback {
164 my $self = shift;
165 my ($meta_instance, $instance, $slot_name) = @_;
166
167 return sub {
168 $meta_instance->set_slot_value($instance, $slot_name, $_[0]);
169 };
170}
171
172sub get_read_method {
173 my $self = shift;
174 my $reader = $self->reader || $self->accessor;
175 # normal case ...
176 return $reader unless ref $reader;
177 # the HASH ref case
178 my ($name) = %$reader;
179 return $name;
180}
181
182sub get_write_method {
183 my $self = shift;
184 my $writer = $self->writer || $self->accessor;
185 # normal case ...
186 return $writer unless ref $writer;
187 # the HASH ref case
188 my ($name) = %$writer;
189 return $name;
190}
191
192sub get_read_method_ref {
193 my $self = shift;
194 if ((my $reader = $self->get_read_method) && $self->associated_class) {
195 return $self->associated_class->get_method($reader);
196 }
197 else {
198 my $code = sub { $self->get_value(@_) };
199 if (my $class = $self->associated_class) {
200 return $class->method_metaclass->wrap(
201 $code,
202 package_name => $class->name,
203 name => '__ANON__'
204 );
205 }
206 else {
207 return $code;
208 }
209 }
210}
211
212sub get_write_method_ref {
213 my $self = shift;
214 if ((my $writer = $self->get_write_method) && $self->associated_class) {
215 return $self->associated_class->get_method($writer);
216 }
217 else {
218 my $code = sub { $self->set_value(@_) };
219 if (my $class = $self->associated_class) {
220 return $class->method_metaclass->wrap(
221 $code,
222 package_name => $class->name,
223 name => '__ANON__'
224 );
225 }
226 else {
227 return $code;
228 }
229 }
230}
231
232# slots
233
2344421.60ms442261µs
# spent 1.31ms (1.05+261µs) within Class::MOP::Attribute::slots which was called 442 times, avg 3µs/call: # 442 times (1.05ms+261µs) by Class::MOP::Instance::BUILDARGS at line 33 of Class/MOP/Instance.pm, avg 3µs/call
sub slots { (shift)->name }
# spent 261µs making 442 calls to Class::MOP::Mixin::AttributeCore::name, avg 591ns/call
235
236# class association
237
238
# spent 1.19ms (884µs+305µs) within Class::MOP::Attribute::attach_to_class which was called 131 times, avg 9µs/call: # 131 times (884µs+305µs) by Class::MOP::Class::_attach_attribute at line 880 of Class/MOP/Class.pm, avg 9µs/call
sub attach_to_class {
2393931.26ms my ($self, $class) = @_;
240262187µs (blessed($class) && $class->isa('Class::MOP::Class'))
# spent 94µs making 131 calls to Scalar::Util::blessed, avg 715ns/call # spent 93µs making 131 calls to UNIVERSAL::isa, avg 712ns/call
241 || confess "You must pass a Class::MOP::Class instance (or a subclass)";
242131118µs weaken($self->{'associated_class'} = $class);
# spent 118µs making 131 calls to Scalar::Util::weaken, avg 903ns/call
243}
244
245sub detach_from_class {
246 my $self = shift;
247 $self->{'associated_class'} = undef;
248}
249
250# method association
251
252
# spent 572µs within Class::MOP::Attribute::associate_method which was called 254 times, avg 2µs/call: # 197 times (473µs+0s) by Class::MOP::Attribute::_process_accessors at line 402, avg 2µs/call # 57 times (99µs+0s) by Class::MOP::Attribute::_process_accessors at line 380, avg 2µs/call
sub associate_method {
253508753µs my ($self, $method) = @_;
254 push @{$self->{'associated_methods'}} => $method;
255}
256
257## Slot management
258
259
# spent 138µs (41+97) within Class::MOP::Attribute::set_initial_value which was called 4 times, avg 35µs/call: # 4 times (41µs+97µs) by Moose::Meta::Attribute::initialize_instance_slot at line 533 of Moose/Meta/Attribute.pm, avg 35µs/call
sub set_initial_value {
260833µs my ($self, $instance, $value) = @_;
2611297µs $self->_set_initial_slot_value(
# spent 61µs making 4 calls to Class::MOP::Attribute::_set_initial_slot_value, avg 15µs/call # spent 30µs making 4 calls to Class::MOP::Class::initialize, avg 7µs/call # spent 7µs making 4 calls to Class::MOP::Class::get_meta_instance, avg 2µs/call
262 Class::MOP::Class->initialize(ref($instance))->get_meta_instance,
263 $instance,
264 $value
265 );
266}
267
268sub set_value { shift->set_raw_value(@_) }
269
270sub set_raw_value {
271 my $self = shift;
272 my ($instance, $value) = @_;
273
274 my $mi = Class::MOP::Class->initialize(ref($instance))->get_meta_instance;
275 return $mi->set_slot_value($instance, $self->name, $value);
276}
277
278
# spent 13.5ms (1.21+12.3) within Class::MOP::Attribute::_inline_set_value which was called 402 times, avg 34µs/call: # 273 times (801µs+7.36ms) by Class::MOP::Class::_inline_init_attr_from_constructor at line 630 of Class/MOP/Class.pm, avg 30µs/call # 96 times (264µs+2.05ms) by Class::MOP::Class::_inline_init_attr_from_default at line 651 of Class/MOP/Class.pm, avg 24µs/call # 22 times (88µs+1.75ms) by Class::MOP::Method::Accessor::__ANON__[/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/x86_64-linux/Class/MOP/Method/Accessor.pm:120] at line 112 of Class/MOP/Method/Accessor.pm, avg 83µs/call # 8 times (42µs+1.07ms) by Moose::Meta::Attribute::_inline_set_value at line 623 of Moose/Meta/Attribute.pm, avg 139µs/call # 3 times (14µs+65µs) by Class::MOP::Method::Accessor::__ANON__[/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/x86_64-linux/Class/MOP/Method/Accessor.pm:184] at line 179 of Class/MOP/Method/Accessor.pm, avg 26µs/call
sub _inline_set_value {
2798041.25ms my $self = shift;
28040212.3ms return $self->_inline_instance_set(@_) . ';';
# spent 12.3ms making 402 calls to Class::MOP::Attribute::_inline_instance_set, avg 31µs/call
281}
282
283
# spent 12.3ms (3.30+9.00) within Class::MOP::Attribute::_inline_instance_set which was called 403 times, avg 31µs/call: # 402 times (3.30ms+8.99ms) by Class::MOP::Attribute::_inline_set_value at line 280, avg 31µs/call # once (8µs+8µs) by Moose::Meta::Attribute::_inline_init_slot at line 968 of Moose/Meta/Attribute.pm
sub _inline_instance_set {
28416123.47ms my $self = shift;
285 my ($instance, $value) = @_;
286
2878066.30ms my $mi = $self->associated_class->get_meta_instance;
# spent 3.56ms making 252 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance, avg 14µs/call # spent 2.53ms making 151 calls to Class::MOP::Class::get_meta_instance, avg 17µs/call # spent 205µs making 403 calls to Class::MOP::Attribute::associated_class, avg 508ns/call
2888062.70ms return $mi->inline_set_slot_value($instance, $self->name, $value);
# spent 2.47ms making 403 calls to Class::MOP::Instance::inline_set_slot_value, avg 6µs/call # spent 231µs making 403 calls to Class::MOP::Mixin::AttributeCore::name, avg 574ns/call
289}
290
2911237µs12307µs
# spent 339µs (33+307) within Class::MOP::Attribute::get_value which was called 12 times, avg 28µs/call: # 12 times (33µs+307µs) by Moose::Meta::Mixin::AttributeCore::is_lazy or Moose::Meta::Mixin::AttributeCore::is_required or Moose::Meta::Mixin::AttributeCore::is_weak_ref or Moose::Meta::Mixin::AttributeCore::should_auto_deref or Moose::Meta::Mixin::AttributeCore::should_coerce at line 133 of Class/MOP/Method/Accessor.pm, avg 28µs/call
sub get_value { shift->get_raw_value(@_) }
# spent 307µs making 12 calls to Class::MOP::Attribute::get_raw_value, avg 26µs/call
292
293
# spent 307µs (126+181) within Class::MOP::Attribute::get_raw_value which was called 12 times, avg 26µs/call: # 12 times (126µs+181µs) by Class::MOP::Attribute::get_value at line 291, avg 26µs/call
sub get_raw_value {
29448103µs my $self = shift;
295 my ($instance) = @_;
296
29724149µs my $mi = Class::MOP::Class->initialize(ref($instance))->get_meta_instance;
# spent 87µs making 10 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance, avg 9µs/call # spent 59µs making 12 calls to Class::MOP::Class::initialize, avg 5µs/call # spent 2µs making 2 calls to Class::MOP::Class::get_meta_instance, avg 1µs/call
2982432µs return $mi->get_slot_value($instance, $self->name);
# spent 23µs making 12 calls to Class::MOP::Instance::get_slot_value, avg 2µs/call # spent 9µs making 12 calls to Class::MOP::Mixin::AttributeCore::name, avg 767ns/call
299}
300
301
# spent 3.45ms (268µs+3.18) within Class::MOP::Attribute::_inline_get_value which was called 75 times, avg 46µs/call: # 53 times (187µs+2.81ms) by Class::MOP::Method::Accessor::__ANON__[/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/x86_64-linux/Class/MOP/Method/Accessor.pm:154] at line 142 of Class/MOP/Method/Accessor.pm, avg 57µs/call # 22 times (81µs+366µs) by Class::MOP::Method::Accessor::__ANON__[/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/x86_64-linux/Class/MOP/Method/Accessor.pm:120] at line 112 of Class/MOP/Method/Accessor.pm, avg 20µs/call
sub _inline_get_value {
302150324µs my $self = shift;
303753.18ms return $self->_inline_instance_get(@_) . ';';
# spent 3.18ms making 75 calls to Class::MOP::Attribute::_inline_instance_get, avg 42µs/call
304}
305
306
# spent 3.62ms (783µs+2.84) within Class::MOP::Attribute::_inline_instance_get which was called 84 times, avg 43µs/call: # 75 times (680µs+2.50ms) by Class::MOP::Attribute::_inline_get_value at line 303, avg 42µs/call # 9 times (103µs+339µs) by Moose::Meta::Attribute::_inline_get_value at line 870 of Moose/Meta/Attribute.pm, avg 49µs/call
sub _inline_instance_get {
307336816µs my $self = shift;
308 my ($instance) = @_;
309
3101682.22ms my $mi = $self->associated_class->get_meta_instance;
# spent 2.17ms making 84 calls to Class::MOP::Class::get_meta_instance, avg 26µs/call # spent 44µs making 84 calls to Class::MOP::Attribute::associated_class, avg 526ns/call
311168622µs return $mi->inline_get_slot_value($instance, $self->name);
# spent 572µs making 84 calls to Class::MOP::Instance::inline_get_slot_value, avg 7µs/call # spent 50µs making 84 calls to Class::MOP::Mixin::AttributeCore::name, avg 596ns/call
312}
313
314
# spent 274µs (115+159) within Class::MOP::Attribute::has_value which was called 12 times, avg 23µs/call: # 12 times (115µs+159µs) by Moose::Meta::Mixin::AttributeCore::has_handles or Moose::Meta::Mixin::AttributeCore::has_trigger or Moose::Meta::Mixin::AttributeCore::has_type_constraint at line 195 of Class/MOP/Method/Accessor.pm, avg 23µs/call
sub has_value {
31548108µs my $self = shift;
316 my ($instance) = @_;
317
31824125µs my $mi = Class::MOP::Class->initialize(ref($instance))->get_meta_instance;
# spent 64µs making 9 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance, avg 7µs/call # spent 57µs making 12 calls to Class::MOP::Class::initialize, avg 5µs/call # spent 4µs making 3 calls to Class::MOP::Class::get_meta_instance, avg 1µs/call
3192434µs return $mi->is_slot_initialized($instance, $self->name);
# spent 25µs making 12 calls to Class::MOP::Instance::is_slot_initialized, avg 2µs/call # spent 9µs making 12 calls to Class::MOP::Mixin::AttributeCore::name, avg 792ns/call
320}
321
322
# spent 392µs (66+326) within Class::MOP::Attribute::_inline_has_value which was called 16 times, avg 24µs/call: # 16 times (66µs+326µs) by Class::MOP::Method::Accessor::__ANON__[/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/x86_64-linux/Class/MOP/Method/Accessor.pm:209] at line 204 of Class/MOP/Method/Accessor.pm, avg 24µs/call
sub _inline_has_value {
3233275µs my $self = shift;
32416326µs return $self->_inline_instance_has(@_) . ';';
# spent 326µs making 16 calls to Class::MOP::Attribute::_inline_instance_has, avg 20µs/call
325}
326
327
# spent 348µs (181+167) within Class::MOP::Attribute::_inline_instance_has which was called 17 times, avg 20µs/call: # 16 times (167µs+158µs) by Class::MOP::Attribute::_inline_has_value at line 324, avg 20µs/call # once (14µs+9µs) by Moose::Meta::Attribute::_inline_check_lazy at line 887 of Moose/Meta/Attribute.pm
sub _inline_instance_has {
32868183µs my $self = shift;
329 my ($instance) = @_;
330
3313432µs my $mi = $self->associated_class->get_meta_instance;
# spent 23µs making 17 calls to Class::MOP::Class::get_meta_instance, avg 1µs/call # spent 9µs making 17 calls to Class::MOP::Attribute::associated_class, avg 529ns/call
33234135µs return $mi->inline_is_slot_initialized($instance, $self->name);
# spent 125µs making 17 calls to Class::MOP::Instance::inline_is_slot_initialized, avg 7µs/call # spent 10µs making 17 calls to Class::MOP::Mixin::AttributeCore::name, avg 588ns/call
333}
334
335sub clear_value {
336 my $self = shift;
337 my ($instance) = @_;
338
339 my $mi = Class::MOP::Class->initialize(ref($instance))->get_meta_instance;
340 return $mi->deinitialize_slot($instance, $self->name);
341}
342
343sub _inline_clear_value {
344 my $self = shift;
345 return $self->_inline_instance_clear(@_) . ';';
346}
347
348sub _inline_instance_clear {
349 my $self = shift;
350 my ($instance) = @_;
351
352 my $mi = $self->associated_class->get_meta_instance;
353 return $mi->inline_deinitialize_slot($instance, $self->name);
354}
355
356## load em up ...
357
358245577µs
# spent 291µs within Class::MOP::Attribute::accessor_metaclass which was called 245 times, avg 1µs/call: # 188 times (197µs+0s) by Class::MOP::Attribute::__ANON__[/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/x86_64-linux/Class/MOP/Attribute.pm:398] at line 389, avg 1µs/call # 57 times (94µs+0s) by Class::MOP::Attribute::_process_accessors at line 372, avg 2µs/call
sub accessor_metaclass { 'Class::MOP::Method::Accessor' }
359
360
# spent 66.3ms (5.91+60.3) within Class::MOP::Attribute::_process_accessors which was called 254 times, avg 261µs/call: # 150 times (3.46ms+26.9ms) by Class::MOP::Attribute::install_accessors at line 428, avg 202µs/call # 45 times (1.16ms+11.3ms) by Class::MOP::Attribute::install_accessors at line 424, avg 276µs/call # 42 times (842µs+6.09ms) by Class::MOP::Attribute::install_accessors at line 436, avg 165µs/call # 9 times (292µs+14.8ms) by Moose::Meta::Attribute::_process_accessors at line 1074 of Moose/Meta/Attribute.pm, avg 1.68ms/call # 8 times (157µs+1.25ms) by Class::MOP::Attribute::install_accessors at line 432, avg 176µs/call
sub _process_accessors {
36120895.81ms my ($self, $type, $accessor, $generate_as_inline_methods) = @_;
362
363254190µs my $method_ctx = { %{ $self->definition_context || {} } };
# spent 190µs making 254 calls to Class::MOP::Mixin::AttributeCore::definition_context, avg 750ns/call
364
365 if (ref($accessor)) {
366 (ref($accessor) eq 'HASH')
367 || confess "bad accessor/reader/writer/predicate/clearer format, must be a HASH ref";
368 my ($name, $method) = %{$accessor};
369
37057551µs $method_ctx->{description} = $self->_accessor_description($name, $type);
# spent 551µs making 57 calls to Class::MOP::Attribute::_accessor_description, avg 10µs/call
371
3722852.81ms $method = $self->accessor_metaclass->wrap(
# spent 2.64ms making 57 calls to Class::MOP::Method::wrap, avg 46µs/call # spent 94µs making 57 calls to Class::MOP::Attribute::accessor_metaclass, avg 2µs/call # spent 52µs making 114 calls to Class::MOP::Attribute::associated_class, avg 460ns/call # spent 24µs making 57 calls to Class::MOP::Package::name, avg 416ns/call
373 $method,
374 attribute => $self,
375 package_name => $self->associated_class->name,
376 name => $name,
377 associated_metaclass => $self->associated_class,
378 definition_context => $method_ctx,
379 );
3805799µs $self->associate_method($method);
# spent 99µs making 57 calls to Class::MOP::Attribute::associate_method, avg 2µs/call
381 return ($name, $method);
382 }
383 else {
384285202µs my $inline_me = ($generate_as_inline_methods && $self->associated_class->instance_metaclass->is_inlinable);
# spent 94µs making 95 calls to Class::MOP::Instance::is_inlinable, avg 992ns/call # spent 58µs making 95 calls to Class::MOP::Class::instance_metaclass, avg 609ns/call # spent 50µs making 95 calls to Class::MOP::Attribute::associated_class, avg 522ns/call
385 my $method;
386
# spent 53.2ms (3.01+50.2) within Class::MOP::Attribute::__ANON__[/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/x86_64-linux/Class/MOP/Attribute.pm:398] which was called 197 times, avg 270µs/call: # 197 times (3.01ms+50.2ms) by Try::Tiny::try at line 76 of Try/Tiny.pm, avg 270µs/call
try {
3873942.77ms1972.23ms $method_ctx->{description} = $self->_accessor_description($accessor, $type);
# spent 2.23ms making 197 calls to Class::MOP::Attribute::_accessor_description, avg 11µs/call
388
38998533.8ms $method = $self->accessor_metaclass->new(
# spent 33.2ms making 188 calls to Class::MOP::Method::Accessor::new, avg 177µs/call # spent 197µs making 188 calls to Class::MOP::Attribute::accessor_metaclass, avg 1µs/call # spent 185µs making 394 calls to Class::MOP::Attribute::associated_class, avg 469ns/call # spent 89µs making 197 calls to Class::MOP::Package::name, avg 451ns/call # spent 42µs making 9 calls to Moose::Meta::Method::Accessor::new, avg 5µs/call # spent 14µs making 9 calls to Moose::Meta::Attribute::accessor_metaclass, avg 2µs/call
390 attribute => $self,
391 is_inline => $inline_me,
392 accessor_type => $type,
393 package_name => $self->associated_class->name,
394 name => $accessor,
395 associated_metaclass => $self->associated_class,
396 definition_context => $method_ctx,
397 );
398 }
399 catch {
400 confess "Could not create the '$type' method for " . $self->name . " because : $_";
40139433.9ms };
# spent 55.5ms making 197 calls to Try::Tiny::try, avg 282µs/call, recursion: max depth 1, sum of overlapping time 22.1ms # spent 536µs making 197 calls to Try::Tiny::catch, avg 3µs/call
402197473µs $self->associate_method($method);
# spent 473µs making 197 calls to Class::MOP::Attribute::associate_method, avg 2µs/call
403 return ($accessor, $method);
404 }
405}
406
407
# spent 2.78ms (2.32+457µs) within Class::MOP::Attribute::_accessor_description which was called 254 times, avg 11µs/call: # 197 times (1.86ms+368µs) by Class::MOP::Attribute::__ANON__[/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/x86_64-linux/Class/MOP/Attribute.pm:398] at line 387, avg 11µs/call # 57 times (462µs+88µs) by Class::MOP::Attribute::_process_accessors at line 370, avg 10µs/call
sub _accessor_description {
40812703.05ms my $self = shift;
409 my ($name, $type) = @_;
410
411508281µs my $desc = "$type " . $self->associated_class->name . "::$name";
# spent 145µs making 254 calls to Class::MOP::Package::name, avg 572ns/call # spent 135µs making 254 calls to Class::MOP::Attribute::associated_class, avg 532ns/call
412360176µs if ( $name ne $self->name ) {
# spent 176µs making 360 calls to Class::MOP::Mixin::AttributeCore::name, avg 489ns/call
413 $desc .= " of attribute " . $self->name;
414 }
415
416 return $desc;
417}
418
419
# spent 90.2ms (4.90+85.3) within Class::MOP::Attribute::install_accessors which was called 207 times, avg 436µs/call: # 122 times (2.75ms+25.8ms) by Class::MOP::Class::__ANON__[/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/x86_64-linux/Class/MOP/Class.pm:892] at line 891 of Class/MOP/Class.pm, avg 234µs/call # 75 times (1.75ms+42.3ms) by Class::MOP::Class::_inline_accessors at line 1413 of Class/MOP/Class.pm, avg 587µs/call # 10 times (402µs+17.3ms) by Moose::Meta::Attribute::install_accessors at line 1013 of Moose/Meta/Attribute.pm, avg 1.77ms/call
sub install_accessors {
42018634.25ms my $self = shift;
421 my $inline = shift;
422207153µs my $class = $self->associated_class;
# spent 153µs making 207 calls to Class::MOP::Attribute::associated_class, avg 742ns/call
423
42436027.5ms $class->add_method(
# spent 12.4ms making 45 calls to Class::MOP::Attribute::_process_accessors, avg 276µs/call # spent 11.0ms making 6 calls to Moose::Meta::Attribute::_process_accessors, avg 1.83ms/call # spent 3.75ms making 51 calls to Class::MOP::Mixin::HasMethods::add_method, avg 74µs/call # spent 347µs making 207 calls to Class::MOP::Mixin::AttributeCore::has_accessor, avg 2µs/call # spent 45µs making 51 calls to Class::MOP::Mixin::AttributeCore::accessor, avg 875ns/call
425 $self->_process_accessors('accessor' => $self->accessor(), $inline)
426 ) if $self->has_accessor();
427
42866645.8ms $class->add_method(
# spent 30.3ms making 150 calls to Class::MOP::Attribute::_process_accessors, avg 202µs/call # spent 9.75ms making 153 calls to Class::MOP::Mixin::HasMethods::add_method, avg 64µs/call # spent 5.32ms making 3 calls to Moose::Meta::Attribute::_process_accessors, avg 1.77ms/call # spent 294µs making 207 calls to Class::MOP::Mixin::AttributeCore::has_reader, avg 1µs/call # spent 115µs making 153 calls to Class::MOP::Mixin::AttributeCore::reader, avg 752ns/call
429 $self->_process_accessors('reader' => $self->reader(), $inline)
430 ) if $self->has_reader();
431
4322312.12ms $class->add_method(
# spent 1.41ms making 8 calls to Class::MOP::Attribute::_process_accessors, avg 176µs/call # spent 429µs making 8 calls to Class::MOP::Mixin::HasMethods::add_method, avg 54µs/call # spent 278µs making 207 calls to Class::MOP::Mixin::AttributeCore::has_writer, avg 1µs/call # spent 6µs making 8 calls to Class::MOP::Mixin::AttributeCore::writer, avg 788ns/call
433 $self->_process_accessors('writer' => $self->writer(), $inline)
434 ) if $self->has_writer();
435
4363339.47ms $class->add_method(
# spent 6.93ms making 42 calls to Class::MOP::Attribute::_process_accessors, avg 165µs/call # spent 2.25ms making 42 calls to Class::MOP::Mixin::HasMethods::add_method, avg 54µs/call # spent 252µs making 207 calls to Class::MOP::Mixin::AttributeCore::has_predicate, avg 1µs/call # spent 33µs making 42 calls to Class::MOP::Mixin::AttributeCore::predicate, avg 783ns/call
437 $self->_process_accessors('predicate' => $self->predicate(), $inline)
438 ) if $self->has_predicate();
439
440207246µs $class->add_method(
# spent 246µs making 207 calls to Class::MOP::Mixin::AttributeCore::has_clearer, avg 1µs/call
441 $self->_process_accessors('clearer' => $self->clearer(), $inline)
442 ) if $self->has_clearer();
443
444 return;
445}
446
447{
4481300ns my $_remove_accessor = sub {
449 my ($accessor, $class) = @_;
450 if (ref($accessor) && ref($accessor) eq 'HASH') {
451 ($accessor) = keys %{$accessor};
452 }
453 my $method = $class->get_method($accessor);
454 $class->remove_method($accessor)
455 if (ref($method) && $method->isa('Class::MOP::Method::Accessor'));
45613µs };
457
458 sub remove_accessors {
459 my $self = shift;
460 # TODO:
461 # we really need to make sure to remove from the
462 # associates methods here as well. But this is
463 # such a slimly used method, I am not worried
464 # about it right now.
465 $_remove_accessor->($self->accessor(), $self->associated_class()) if $self->has_accessor();
466 $_remove_accessor->($self->reader(), $self->associated_class()) if $self->has_reader();
467 $_remove_accessor->($self->writer(), $self->associated_class()) if $self->has_writer();
468 $_remove_accessor->($self->predicate(), $self->associated_class()) if $self->has_predicate();
469 $_remove_accessor->($self->clearer(), $self->associated_class()) if $self->has_clearer();
470 return;
471 }
472
473}
474
47515µs1;
476
477# ABSTRACT: Attribute Meta Object
478
- -
481=pod
482
483=head1 NAME
484
485Class::MOP::Attribute - Attribute Meta Object
486
487=head1 VERSION
488
489version 2.0602
490
491=head1 SYNOPSIS
492
493 Class::MOP::Attribute->new(
494 foo => (
495 accessor => 'foo', # dual purpose get/set accessor
496 predicate => 'has_foo', # predicate check for defined-ness
497 init_arg => '-foo', # class->new will look for a -foo key
498 default => 'BAR IS BAZ!' # if no -foo key is provided, use this
499 )
500 );
501
502 Class::MOP::Attribute->new(
503 bar => (
504 reader => 'bar', # getter
505 writer => 'set_bar', # setter
506 predicate => 'has_bar', # predicate check for defined-ness
507 init_arg => ':bar', # class->new will look for a :bar key
508 # no default value means it is undef
509 )
510 );
511
512=head1 DESCRIPTION
513
514The Attribute Protocol is almost entirely an invention of
515C<Class::MOP>. Perl 5 does not have a consistent notion of
516attributes. There are so many ways in which this is done, and very few
517(if any) are easily discoverable by this module.
518
519With that said, this module attempts to inject some order into this
520chaos, by introducing a consistent API which can be used to create
521object attributes.
522
523=head1 METHODS
524
525=head2 Creation
526
527=over 4
528
529=item B<< Class::MOP::Attribute->new($name, ?%options) >>
530
531An attribute must (at the very least), have a C<$name>. All other
532C<%options> are added as key-value pairs.
533
534=over 8
535
536=item * init_arg
537
538This is a string value representing the expected key in an
539initialization hash. For instance, if we have an C<init_arg> value of
540C<-foo>, then the following code will Just Work.
541
542 MyClass->meta->new_object( -foo => 'Hello There' );
543
544If an init_arg is not assigned, it will automatically use the
545attribute's name. If C<init_arg> is explicitly set to C<undef>, the
546attribute cannot be specified during initialization.
547
548=item * builder
549
550This provides the name of a method that will be called to initialize
551the attribute. This method will be called on the object after it is
552constructed. It is expected to return a valid value for the attribute.
553
554=item * default
555
556This can be used to provide an explicit default for initializing the
557attribute. If the default you provide is a subroutine reference, then
558this reference will be called I<as a method> on the object.
559
560If the value is a simple scalar (string or number), then it can be
561just passed as is. However, if you wish to initialize it with a HASH
562or ARRAY ref, then you need to wrap that inside a subroutine
563reference:
564
565 Class::MOP::Attribute->new(
566 'foo' => (
567 default => sub { [] },
568 )
569 );
570
571 # or ...
572
573 Class::MOP::Attribute->new(
574 'foo' => (
575 default => sub { {} },
576 )
577 );
578
579If you wish to initialize an attribute with a subroutine reference
580itself, then you need to wrap that in a subroutine as well:
581
582 Class::MOP::Attribute->new(
583 'foo' => (
584 default => sub {
585 sub { print "Hello World" }
586 },
587 )
588 );
589
590And lastly, if the value of your attribute is dependent upon some
591other aspect of the instance structure, then you can take advantage of
592the fact that when the C<default> value is called as a method:
593
594 Class::MOP::Attribute->new(
595 'object_identity' => (
596 default => sub { Scalar::Util::refaddr( $_[0] ) },
597 )
598 );
599
600Note that there is no guarantee that attributes are initialized in any
601particular order, so you cannot rely on the value of some other
602attribute when generating the default.
603
604=item * initializer
605
606This option can be either a method name or a subroutine
607reference. This method will be called when setting the attribute's
608value in the constructor. Unlike C<default> and C<builder>, the
609initializer is only called when a value is provided to the
610constructor. The initializer allows you to munge this value during
611object construction.
612
613The initializer is called as a method with three arguments. The first
614is the value that was passed to the constructor. The second is a
615subroutine reference that can be called to actually set the
616attribute's value, and the last is the associated
617C<Class::MOP::Attribute> object.
618
619This contrived example shows an initializer that sets the attribute to
620twice the given value.
621
622 Class::MOP::Attribute->new(
623 'doubled' => (
624 initializer => sub {
625 my ( $self, $value, $set, $attr ) = @_;
626 $set->( $value * 2 );
627 },
628 )
629 );
630
631Since an initializer can be a method name, you can easily make
632attribute initialization use the writer:
633
634 Class::MOP::Attribute->new(
635 'some_attr' => (
636 writer => 'some_attr',
637 initializer => 'some_attr',
638 )
639 );
640
641Your writer (actually, a wrapper around the writer, using
642L<method modifications|Moose::Manual::MethodModifiers>) will need to examine
643C<@_> and determine under which
644context it is being called:
645
646 around 'some_attr' => sub {
647 my $orig = shift;
648 my $self = shift;
649 # $value is not defined if being called as a reader
650 # $setter and $attr are only defined if being called as an initializer
651 my ($value, $setter, $attr) = @_;
652
653 # the reader behaves normally
654 return $self->$orig if not @_;
655
656 # mutate $value as desired
657 # $value = <something($value);
658
659 # if called as an initializer, set the value and we're done
660 return $setter->($row) if $setter;
661
662 # otherwise, call the real writer with the new value
663 $self->$orig($row);
664 };
665
666=back
667
668The C<accessor>, C<reader>, C<writer>, C<predicate> and C<clearer>
669options all accept the same parameters. You can provide the name of
670the method, in which case an appropriate default method will be
671generated for you. Or instead you can also provide hash reference
672containing exactly one key (the method name) and one value. The value
673should be a subroutine reference, which will be installed as the
674method itself.
675
676=over 8
677
678=item * accessor
679
680An C<accessor> is a standard Perl-style read/write accessor. It will
681return the value of the attribute, and if a value is passed as an
682argument, it will assign that value to the attribute.
683
684Note that C<undef> is a legitimate value, so this will work:
685
686 $object->set_something(undef);
687
688=item * reader
689
690This is a basic read-only accessor. It returns the value of the
691attribute.
692
693=item * writer
694
695This is a basic write accessor, it accepts a single argument, and
696assigns that value to the attribute.
697
698Note that C<undef> is a legitimate value, so this will work:
699
700 $object->set_something(undef);
701
702=item * predicate
703
704The predicate method returns a boolean indicating whether or not the
705attribute has been explicitly set.
706
707Note that the predicate returns true even if the attribute was set to
708a false value (C<0> or C<undef>).
709
710=item * clearer
711
712This method will uninitialize the attribute. After an attribute is
713cleared, its C<predicate> will return false.
714
715=item * definition_context
716
717Mostly, this exists as a hook for the benefit of Moose.
718
719This option should be a hash reference containing several keys which
720will be used when inlining the attribute's accessors. The keys should
721include C<line>, the line number where the attribute was created, and
722either C<file> or C<description>.
723
724This information will ultimately be used when eval'ing inlined
725accessor code so that error messages report a useful line and file
726name.
727
728=back
729
730=item B<< $attr->clone(%options) >>
731
732This clones the attribute. Any options you provide will override the
733settings of the original attribute. You can change the name of the new
734attribute by passing a C<name> key in C<%options>.
735
736=back
737
738=head2 Informational
739
740These are all basic read-only accessors for the values passed into
741the constructor.
742
743=over 4
744
745=item B<< $attr->name >>
746
747Returns the attribute's name.
748
749=item B<< $attr->accessor >>
750
751=item B<< $attr->reader >>
752
753=item B<< $attr->writer >>
754
755=item B<< $attr->predicate >>
756
757=item B<< $attr->clearer >>
758
759The C<accessor>, C<reader>, C<writer>, C<predicate>, and C<clearer>
760methods all return exactly what was passed to the constructor, so it
761can be either a string containing a method name, or a hash reference.
762
763=item B<< $attr->initializer >>
764
765Returns the initializer as passed to the constructor, so this may be
766either a method name or a subroutine reference.
767
768=item B<< $attr->init_arg >>
769
770=item B<< $attr->is_default_a_coderef >>
771
772=item B<< $attr->builder >>
773
774=item B<< $attr->default($instance) >>
775
776The C<$instance> argument is optional. If you don't pass it, the
777return value for this method is exactly what was passed to the
778constructor, either a simple scalar or a subroutine reference.
779
780If you I<do> pass an C<$instance> and the default is a subroutine
781reference, then the reference is called as a method on the
782C<$instance> and the generated value is returned.
783
784=item B<< $attr->slots >>
785
786Return a list of slots required by the attribute. This is usually just
787one, the name of the attribute.
788
789A slot is the name of the hash key used to store the attribute in an
790object instance.
791
792=item B<< $attr->get_read_method >>
793
794=item B<< $attr->get_write_method >>
795
796Returns the name of a method suitable for reading or writing the value
797of the attribute in the associated class.
798
799If an attribute is read- or write-only, then these methods can return
800C<undef> as appropriate.
801
802=item B<< $attr->has_read_method >>
803
804=item B<< $attr->has_write_method >>
805
806This returns a boolean indicating whether the attribute has a I<named>
807read or write method.
808
809=item B<< $attr->get_read_method_ref >>
810
811=item B<< $attr->get_write_method_ref >>
812
813Returns the subroutine reference of a method suitable for reading or
814writing the attribute's value in the associated class. These methods
815always return a subroutine reference, regardless of whether or not the
816attribute is read- or write-only.
817
818=item B<< $attr->insertion_order >>
819
820If this attribute has been inserted into a class, this returns a zero
821based index regarding the order of insertion.
822
823=back
824
825=head2 Informational predicates
826
827These are all basic predicate methods for the values passed into C<new>.
828
829=over 4
830
831=item B<< $attr->has_accessor >>
832
833=item B<< $attr->has_reader >>
834
835=item B<< $attr->has_writer >>
836
837=item B<< $attr->has_predicate >>
838
839=item B<< $attr->has_clearer >>
840
841=item B<< $attr->has_initializer >>
842
843=item B<< $attr->has_init_arg >>
844
845This will be I<false> if the C<init_arg> was set to C<undef>.
846
847=item B<< $attr->has_default >>
848
849This will be I<false> if the C<default> was set to C<undef>, since
850C<undef> is the default C<default> anyway.
851
852=item B<< $attr->has_builder >>
853
854=item B<< $attr->has_insertion_order >>
855
856This will be I<false> if this attribute has not be inserted into a class
857
858=back
859
860=head2 Value management
861
862These methods are basically "back doors" to the instance, and can be
863used to bypass the regular accessors, but still stay within the MOP.
864
865These methods are not for general use, and should only be used if you
866really know what you are doing.
867
868=over 4
869
870=item B<< $attr->initialize_instance_slot($meta_instance, $instance, $params) >>
871
872This method is used internally to initialize the attribute's slot in
873the object C<$instance>.
874
875The C<$params> is a hash reference of the values passed to the object
876constructor.
877
878It's unlikely that you'll need to call this method yourself.
879
880=item B<< $attr->set_value($instance, $value) >>
881
882Sets the value without going through the accessor. Note that this
883works even with read-only attributes.
884
885=item B<< $attr->set_raw_value($instance, $value) >>
886
887Sets the value with no side effects such as a trigger.
888
889This doesn't actually apply to Class::MOP attributes, only to subclasses.
890
891=item B<< $attr->set_initial_value($instance, $value) >>
892
893Sets the value without going through the accessor. This method is only
894called when the instance is first being initialized.
895
896=item B<< $attr->get_value($instance) >>
897
898Returns the value without going through the accessor. Note that this
899works even with write-only accessors.
900
901=item B<< $attr->get_raw_value($instance) >>
902
903Returns the value without any side effects such as lazy attributes.
904
905Doesn't actually apply to Class::MOP attributes, only to subclasses.
906
907=item B<< $attr->has_value($instance) >>
908
909Return a boolean indicating whether the attribute has been set in
910C<$instance>. This how the default C<predicate> method works.
911
912=item B<< $attr->clear_value($instance) >>
913
914This will clear the attribute's value in C<$instance>. This is what
915the default C<clearer> calls.
916
917Note that this works even if the attribute does not have any
918associated read, write or clear methods.
919
920=back
921
922=head2 Class association
923
924These methods allow you to manage the attributes association with
925the class that contains it. These methods should not be used
926lightly, nor are they very magical, they are mostly used internally
927and by metaclass instances.
928
929=over 4
930
931=item B<< $attr->associated_class >>
932
933This returns the C<Class::MOP::Class> with which this attribute is
934associated, if any.
935
936=item B<< $attr->attach_to_class($metaclass) >>
937
938This method stores a weakened reference to the C<$metaclass> object
939internally.
940
941This method does not remove the attribute from its old class,
942nor does it create any accessors in the new class.
943
944It is probably best to use the L<Class::MOP::Class> C<add_attribute>
945method instead.
946
947=item B<< $attr->detach_from_class >>
948
949This method removes the associate metaclass object from the attribute
950it has one.
951
952This method does not remove the attribute itself from the class, or
953remove its accessors.
954
955It is probably best to use the L<Class::MOP::Class>
956C<remove_attribute> method instead.
957
958=back
959
960=head2 Attribute Accessor generation
961
962=over 4
963
964=item B<< $attr->accessor_metaclass >>
965
966Accessor methods are generated using an accessor metaclass. By
967default, this is L<Class::MOP::Method::Accessor>. This method returns
968the name of the accessor metaclass that this attribute uses.
969
970=item B<< $attr->associate_method($method) >>
971
972This associates a L<Class::MOP::Method> object with the
973attribute. Typically, this is called internally when an attribute
974generates its accessors.
975
976=item B<< $attr->associated_methods >>
977
978This returns the list of methods which have been associated with the
979attribute.
980
981=item B<< $attr->install_accessors >>
982
983This method generates and installs code the attributes various
984accessors. It is typically called from the L<Class::MOP::Class>
985C<add_attribute> method.
986
987=item B<< $attr->remove_accessors >>
988
989This method removes all of the accessors associated with the
990attribute.
991
992This does not currently remove methods from the list returned by
993C<associated_methods>.
994
995=item B<< $attr->inline_get >>
996
997=item B<< $attr->inline_set >>
998
999=item B<< $attr->inline_has >>
1000
1001=item B<< $attr->inline_clear >>
1002
1003These methods return a code snippet suitable for inlining the relevant
1004operation. They expect strings containing variable names to be used in the
1005inlining, like C<'$self'> or C<'$_[1]'>.
1006
1007=back
1008
1009=head2 Introspection
1010
1011=over 4
1012
1013=item B<< Class::MOP::Attribute->meta >>
1014
1015This will return a L<Class::MOP::Class> instance for this class.
1016
1017It should also be noted that L<Class::MOP> will actually bootstrap
1018this module by installing a number of attribute meta-objects into its
1019metaclass.
1020
1021=back
1022
1023=head1 AUTHOR
1024
1025Moose is maintained by the Moose Cabal, along with the help of many contributors. See L<Moose/CABAL> and L<Moose/CONTRIBUTORS> for details.
1026
1027=head1 COPYRIGHT AND LICENSE
1028
1029This software is copyright (c) 2012 by Infinity Interactive, Inc..
1030
1031This is free software; you can redistribute it and/or modify it under
1032the same terms as the Perl 5 programming language system itself.
1033
1034=cut
1035
1036
1037__END__