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

File /usr/lib/perl5/vendor_perl/5.10.1/i386-linux-thread-multi/Class/MOP/Attribute.pm
Statements Executed 29640
Statement Execution Time 373ms
Subroutines — ordered by exclusive time
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
19601181.9ms131msClass::MOP::Attribute::::_set_initial_slot_valueClass::MOP::Attribute::_set_initial_slot_value
25061166.0ms256msClass::MOP::Attribute::::initialize_instance_slotClass::MOP::Attribute::initialize_instance_slot
3625247.9ms587msClass::MOP::Attribute::::_process_accessorsClass::MOP::Attribute::_process_accessors
3023241.0ms784msClass::MOP::Attribute::::install_accessorsClass::MOP::Attribute::install_accessors
3051121.1ms481msClass::MOP::Attribute::::__ANON__[:340]Class::MOP::Attribute::__ANON__[:340]
4411118.9ms60.4msClass::MOP::Attribute::::set_raw_valueClass::MOP::Attribute::set_raw_value
12965218.2ms23.4msClass::MOP::Attribute::::slotsClass::MOP::Attribute::slots
23450416.4ms105msClass::MOP::Attribute::::newClass::MOP::Attribute::new
128318410.5ms10.5msClass::MOP::Attribute::::associated_classClass::MOP::Attribute::associated_class
4412210.4ms70.8msClass::MOP::Attribute::::set_valueClass::MOP::Attribute::set_value
234118.31ms12.2msClass::MOP::Attribute::::attach_to_classClass::MOP::Attribute::attach_to_class
376326.32ms6.32msClass::MOP::Attribute::::associate_methodClass::MOP::Attribute::associate_method
115116.25ms15.8msClass::MOP::Attribute::::get_raw_valueClass::MOP::Attribute::get_raw_value
115115.00ms8.90msClass::MOP::Attribute::::_newClass::MOP::Attribute::_new
54331.75ms2.74msClass::MOP::Attribute::::get_read_methodClass::MOP::Attribute::get_read_method
115321.64ms17.4msClass::MOP::Attribute::::get_valueClass::MOP::Attribute::get_value
60321.44ms4.22msClass::MOP::Attribute::::has_valueClass::MOP::Attribute::has_value
223211.31ms1.31msClass::MOP::Attribute::::accessor_metaclassClass::MOP::Attribute::accessor_metaclass
15111.16ms4.48msClass::MOP::Attribute::::get_read_method_refClass::MOP::Attribute::get_read_method_ref
2321763µs2.43msClass::MOP::Attribute::::set_initial_valueClass::MOP::Attribute::set_initial_value
11911749µs749µsClass::MOP::Attribute::::associated_methodsClass::MOP::Attribute::associated_methods
111169µs184µsClass::MOP::Attribute::::BEGIN@4Class::MOP::Attribute::BEGIN@4
211157µs1.32msClass::MOP::Attribute::::remove_accessorsClass::MOP::Attribute::remove_accessors
111132µs192µsClass::MOP::Attribute::::BEGIN@5Class::MOP::Attribute::BEGIN@5
21194µs94µsClass::MOP::Attribute::::detach_from_classClass::MOP::Attribute::detach_from_class
21178µs1.10msClass::MOP::Attribute::::__ANON__[:386]Class::MOP::Attribute::__ANON__[:386]
11134µs368µsClass::MOP::Attribute::::BEGIN@17Class::MOP::Attribute::BEGIN@17
11132µs458µsClass::MOP::Attribute::::BEGIN@9Class::MOP::Attribute::BEGIN@9
11132µs202µsClass::MOP::Attribute::::BEGIN@10Class::MOP::Attribute::BEGIN@10
11132µs233µsClass::MOP::Attribute::::BEGIN@11Class::MOP::Attribute::BEGIN@11
11119µs19µsClass::MOP::Attribute::::BEGIN@7Class::MOP::Attribute::BEGIN@7
0000s0sClass::MOP::Attribute::::__ANON__[:151]Class::MOP::Attribute::__ANON__[:151]
0000s0sClass::MOP::Attribute::::__ANON__[:188]Class::MOP::Attribute::__ANON__[:188]
0000s0sClass::MOP::Attribute::::__ANON__[:208]Class::MOP::Attribute::__ANON__[:208]
0000s0sClass::MOP::Attribute::::__ANON__[:343]Class::MOP::Attribute::__ANON__[:343]
0000s0sClass::MOP::Attribute::::clear_valueClass::MOP::Attribute::clear_value
0000s0sClass::MOP::Attribute::::cloneClass::MOP::Attribute::clone
0000s0sClass::MOP::Attribute::::get_write_methodClass::MOP::Attribute::get_write_method
0000s0sClass::MOP::Attribute::::get_write_method_refClass::MOP::Attribute::get_write_method_ref
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
4386µs2198µs
# spent 184µs (169+15) within Class::MOP::Attribute::BEGIN@4 which was called # once (169µs+15µs) by Class::MOP::BEGIN@19 at line 4
use strict;
# spent 184µs making 1 call to Class::MOP::Attribute::BEGIN@4 # spent 15µs making 1 call to strict::import
5389µs2252µs
# spent 192µs (132+60) within Class::MOP::Attribute::BEGIN@5 which was called # once (132µs+60µs) by Class::MOP::BEGIN@19 at line 5
use warnings;
# spent 192µs making 1 call to Class::MOP::Attribute::BEGIN@5 # spent 60µs making 1 call to warnings::import
6
7381µs119µs
# spent 19µs within Class::MOP::Attribute::BEGIN@7 which was called # once (19µs+0s) by Class::MOP::BEGIN@19 at line 7
use Class::MOP::Method::Accessor;
# spent 19µs making 1 call to Class::MOP::Attribute::BEGIN@7
8
9398µs2885µs
# spent 458µs (32+426) within Class::MOP::Attribute::BEGIN@9 which was called # once (32µs+426µs) by Class::MOP::BEGIN@19 at line 9
use Carp 'confess';
# spent 458µs making 1 call to Class::MOP::Attribute::BEGIN@9 # spent 426µs making 1 call to Exporter::import
10385µs2373µs
# spent 202µs (32+170) within Class::MOP::Attribute::BEGIN@10 which was called # once (32µs+170µs) by Class::MOP::BEGIN@19 at line 10
use Scalar::Util 'blessed', 'weaken';
# spent 202µs making 1 call to Class::MOP::Attribute::BEGIN@10 # spent 170µs making 1 call to Exporter::import
113168µs2435µs
# spent 233µs (32+202) within Class::MOP::Attribute::BEGIN@11 which was called # once (32µs+202µs) by Class::MOP::BEGIN@19 at line 11
use Try::Tiny;
# spent 233µs making 1 call to Class::MOP::Attribute::BEGIN@11 # spent 202µs making 1 call to Exporter::import
12
1314µsour $VERSION = '1.00';
14152µs$VERSION = eval $VERSION;
1512µsour $AUTHORITY = 'cpan:STEVAN';
16
1737.92ms2702µs
# spent 368µs (34+334) within Class::MOP::Attribute::BEGIN@17 which was called # once (34µs+334µs) by Class::MOP::BEGIN@19 at line 17
use base 'Class::MOP::Object', 'Class::MOP::Mixin::AttributeCore';
# spent 368µs making 1 call to Class::MOP::Attribute::BEGIN@17 # spent 334µs making 1 call to base::import
18
19# NOTE: (meta-circularity)
20# This method will be replaced in the
21# boostrap section of Class::MOP, by
22# a new version which uses the
23# &Class::MOP::Class::construct_instance
24# method to build an attribute meta-object
25# which itself is described with attribute
26# meta-objects.
27# - Ain't meta-circularity grand? :)
28
# spent 105ms (16.4+88.1) within Class::MOP::Attribute::new which was called 234 times, avg 447µs/call: # 120 times (7.99ms+82.8ms) by Moose::Meta::Attribute::new at line 70 of Moose/Meta/Attribute.pm, avg 756µs/call # 66 times (5.00ms+3.14ms) by Class::MOP::Mixin::HasAttributes::add_attribute at line 21 of Class/MOP/Mixin/HasAttributes.pm, avg 123µs/call # once (265µs+31µs) by Moose::Exporter::BEGIN@11 at line 325 of Class/MOP.pm # once (176µs+82µs) by Moose::Exporter::BEGIN@11 at line 439 of Class/MOP.pm # once (160µs+94µs) by Moose::Exporter::BEGIN@11 at line 192 of Class/MOP.pm # once (108µs+101µs) by Moose::Exporter::BEGIN@11 at line 349 of Class/MOP.pm # once (168µs+29µs) by Moose::Exporter::BEGIN@11 at line 419 of Class/MOP.pm # once (105µs+89µs) by Moose::Exporter::BEGIN@11 at line 584 of Class/MOP.pm # once (162µs+31µs) by Moose::Exporter::BEGIN@11 at line 523 of Class/MOP.pm # once (89µs+76µs) by Moose::Exporter::BEGIN@11 at line 177 of Class/MOP.pm # once (60µs+95µs) by Moose::Exporter::BEGIN@11 at line 219 of Class/MOP.pm # once (46µs+101µs) by Moose::Exporter::BEGIN@11 at line 505 of Class/MOP.pm # once (47µs+90µs) by Moose::Exporter::BEGIN@11 at line 467 of Class/MOP.pm # once (104µs+32µs) by Moose::Exporter::BEGIN@11 at line 592 of Class/MOP.pm # once (103µs+30µs) by Moose::Exporter::BEGIN@11 at line 558 of Class/MOP.pm # once (48µs+85µs) by Moose::Exporter::BEGIN@11 at line 432 of Class/MOP.pm # once (46µs+86µs) by Moose::Exporter::BEGIN@11 at line 384 of Class/MOP.pm # once (97µs+30µs) by Moose::Exporter::BEGIN@11 at line 453 of Class/MOP.pm # once (94µs+32µs) by Moose::Exporter::BEGIN@11 at line 626 of Class/MOP.pm # once (63µs+48µs) by Moose::Exporter::BEGIN@11 at line 607 of Class/MOP.pm # once (60µs+46µs) by Moose::Exporter::BEGIN@11 at line 306 of Class/MOP.pm # once (57µs+47µs) by Moose::Exporter::BEGIN@11 at line 565 of Class/MOP.pm # once (59µs+42µs) by Moose::Exporter::BEGIN@11 at line 261 of Class/MOP.pm # once (57µs+44µs) by Moose::Exporter::BEGIN@11 at line 495 of Class/MOP.pm # once (58µs+42µs) by Moose::Exporter::BEGIN@11 at line 322 of Class/MOP.pm # once (59µs+42µs) by Moose::Exporter::BEGIN@11 at line 287 of Class/MOP.pm # once (63µs+32µs) by Moose::Exporter::BEGIN@11 at line 517 of Class/MOP.pm # once (57µs+32µs) by Moose::Exporter::BEGIN@11 at line 446 of Class/MOP.pm # once (58µs+31µs) by Moose::Exporter::BEGIN@11 at line 237 of Class/MOP.pm # once (52µs+33µs) by Moose::BEGIN@18 at line 37 of Moose/Meta/Class.pm # once (50µs+35µs) by Moose::Exporter::BEGIN@11 at line 222 of Class/MOP.pm # once (48µs+35µs) by Moose::Exporter::BEGIN@11 at line 511 of Class/MOP.pm # once (53µs+30µs) by Moose::Exporter::BEGIN@11 at line 653 of Class/MOP.pm # once (50µs+32µs) by Moose::Exporter::BEGIN@11 at line 460 of Class/MOP.pm # once (49µs+32µs) by Moose::Exporter::BEGIN@11 at line 180 of Class/MOP.pm # once (47µs+34µs) by Moose::Exporter::BEGIN@11 at line 398 of Class/MOP.pm # once (49µs+32µs) by Moose::Exporter::BEGIN@11 at line 477 of Class/MOP.pm # once (49µs+31µs) by Moose::Exporter::BEGIN@11 at line 412 of Class/MOP.pm # once (46µs+31µs) by Moose::Exporter::BEGIN@11 at line 340 of Class/MOP.pm # once (46µs+31µs) by Moose::Exporter::BEGIN@11 at line 632 of Class/MOP.pm # once (46µs+31µs) by Moose::Exporter::BEGIN@11 at line 358 of Class/MOP.pm # once (45µs+31µs) by Moose::Exporter::BEGIN@11 at line 425 of Class/MOP.pm # once (45µs+30µs) by Moose::Exporter::BEGIN@11 at line 405 of Class/MOP.pm # once (44µs+31µs) by Moose::Exporter::BEGIN@11 at line 551 of Class/MOP.pm # once (45µs+30µs) by Moose::Exporter::BEGIN@11 at line 647 of Class/MOP.pm # once (44µs+30µs) by Moose::Exporter::BEGIN@11 at line 610 of Class/MOP.pm # once (44µs+30µs) by Moose::Exporter::BEGIN@11 at line 529 of Class/MOP.pm # once (44µs+30µs) by Moose::Exporter::BEGIN@11 at line 575 of Class/MOP.pm # once (43µs+30µs) by Moose::Exporter::BEGIN@11 at line 641 of Class/MOP.pm # once (43µs+30µs) by Moose::Exporter::BEGIN@11 at line 368 of Class/MOP.pm
sub new {
29234616.3ms my ( $class, @args ) = @_;
30
31 unshift @args, "name" if @args % 2 == 1;
32 my %options = @args;
33
34 my $name = $options{name};
35
36 (defined $name)
37 || confess "You must provide a name for the attribute";
38
39 $options{init_arg} = $name
40 if not exists $options{init_arg};
41 if(exists $options{builder}){
42 confess("builder must be a defined scalar value which is a method name")
43 if ref $options{builder} || !(defined $options{builder});
44 confess("Setting both default and builder is not allowed.")
45 if exists $options{default};
46 } else {
47 ($class->is_default_a_coderef(\%options))
# spent 830µs making 65 calls to Class::MOP::Mixin::AttributeCore::is_default_a_coderef, avg 13µs/call
48 || confess("References are not allowed as default values, you must ".
49 "wrap the default of '$name' in a CODE reference (ex: sub { [] } and not [])")
50 if exists $options{default} && ref $options{default};
51 }
52 if( $options{required} and not( defined($options{builder}) || defined($options{init_arg}) || exists $options{default} ) ) {
53 confess("A required attribute must have either 'init_arg', 'builder', or 'default'");
54 }
55
56 $class->_new(\%options);
# spent 78.4ms making 119 calls to Moose::Meta::Attribute::_new, avg 658µs/call # spent 8.90ms making 115 calls to Class::MOP::Attribute::_new, avg 77µs/call
57}
58
59
# spent 8.90ms (5.00+3.90) within Class::MOP::Attribute::_new which was called 115 times, avg 77µs/call: # 115 times (5.00ms+3.90ms) by Class::MOP::Attribute::new at line 56, avg 77µs/call
sub _new {
604585.62ms my $class = shift;
61
62 return Class::MOP::Class->initialize($class)->new_object(@_)
# spent 3.87ms making 1 call to Class::MOP::Class::new_object # spent 29µs making 1 call to Class::MOP::Class::initialize
63 if $class ne __PACKAGE__;
64
65 my $options = @_ == 1 ? $_[0] : {@_};
66
67 bless {
68 'name' => $options->{name},
69 'accessor' => $options->{accessor},
70 'reader' => $options->{reader},
71 'writer' => $options->{writer},
72 'predicate' => $options->{predicate},
73 'clearer' => $options->{clearer},
74 'builder' => $options->{builder},
75 'init_arg' => $options->{init_arg},
76 'default' => $options->{default},
77 'initializer' => $options->{initializer},
78 'definition_context' => $options->{definition_context},
79 # keep a weakened link to the
80 # class we are associated with
81 'associated_class' => undef,
82 # and a list of the methods
83 # associated with this attr
84 'associated_methods' => [],
85 # this let's us keep track of
86 # our order inside the associated
87 # class
88 'insertion_order' => undef,
89 }, $class;
90}
91
92# NOTE:
93# this is a primative (and kludgy) clone operation
94# for now, it will be replaced in the Class::MOP
95# bootstrap with a proper one, however we know
96# that this one will work fine for now.
97sub clone {
98 my $self = shift;
99 my %options = @_;
100 (blessed($self))
101 || confess "Can only clone an instance";
102 return bless { %{$self}, %options } => ref($self);
103}
104
105
# spent 256ms (66.0+190) within Class::MOP::Attribute::initialize_instance_slot which was called 2506 times, avg 102µs/call: # 2506 times (66.0ms+190ms) by Class::MOP::Class::_construct_instance at line 364 of Class/MOP/Class.pm, avg 102µs/call
sub initialize_instance_slot {
106751864.1ms my ($self, $meta_instance, $instance, $params) = @_;
107 my $init_arg = $self->{'init_arg'};
108
109 # try to fetch the init arg from the %params ...
110
111 # if nothing was in the %params, we can use the
112 # attribute's default value (if it has one)
113 if(defined $init_arg and exists $params->{$init_arg}){
# spent 131ms making 1960 calls to Class::MOP::Attribute::_set_initial_slot_value, avg 67µs/call # spent 58.4ms making 1105 calls to Class::MOP::Mixin::AttributeCore::default, avg 53µs/call
114 $self->_set_initial_slot_value(
115 $meta_instance,
116 $instance,
117 $params->{$init_arg},
118 );
119 }
120 elsif (defined $self->{'default'}) {
121 $self->_set_initial_slot_value(
122 $meta_instance,
123 $instance,
124 $self->default($instance),
125 );
126 }
127 elsif (defined( my $builder = $self->{'builder'})) {
128 if ($builder = $instance->can($builder)) {
129 $self->_set_initial_slot_value(
130 $meta_instance,
131 $instance,
132 $instance->$builder,
133 );
134 }
135 else {
136 confess(ref($instance)." does not support builder method '". $self->{'builder'} ."' for attribute '" . $self->name . "'");
137 }
138 }
139}
140
141
# spent 131ms (81.9+49.4) within Class::MOP::Attribute::_set_initial_slot_value which was called 1960 times, avg 67µs/call: # 1960 times (81.9ms+49.4ms) by Class::MOP::Attribute::initialize_instance_slot at line 113, avg 67µs/call
sub _set_initial_slot_value {
142588079.6ms my ($self, $meta_instance, $instance, $value) = @_;
143
144 my $slot_name = $self->name;
# spent 8.63ms making 1960 calls to Class::MOP::Mixin::AttributeCore::name, avg 4µs/call
145
146 return $meta_instance->set_slot_value($instance, $slot_name, $value)
# spent 23.9ms making 1960 calls to Class::MOP::Instance::set_slot_value, avg 12µs/call # spent 16.8ms making 1960 calls to Class::MOP::Mixin::AttributeCore::has_initializer, avg 9µs/call
147 unless $self->has_initializer;
148
149 my $callback = sub {
150 $meta_instance->set_slot_value($instance, $slot_name, $_[0]);
151 };
152
153 my $initializer = $self->initializer;
154
155 # most things will just want to set a value, so make it first arg
156 $instance->$initializer($value, $callback, $self);
157}
158
159128316.2ms
# spent 10.5ms within Class::MOP::Attribute::associated_class which was called 1283 times, avg 8µs/call: # 305 times (2.35ms+0s) by Class::MOP::Attribute::__ANON__[/usr/lib/perl5/vendor_perl/5.10.1/i386-linux-thread-multi/Class/MOP/Attribute.pm:340] at line 332, avg 8µs/call # 302 times (2.49ms+0s) by Class::MOP::Attribute::install_accessors at line 352, avg 8µs/call # 139 times (824µs+0s) by Moose::Meta::Attribute::_process_accessors at line 569 of Moose/Meta/Attribute.pm, avg 6µs/call # 105 times (1.06ms+0s) by Moose::Meta::Method::Accessor::_inline_store at line 218 of Moose/Meta/Method/Accessor.pm, avg 10µs/call # 104 times (746µs+0s) by Moose::Meta::Method::Accessor::_inline_get at line 252 of Moose/Meta/Method/Accessor.pm, avg 7µs/call # 84 times (1.15ms+0s) by Class::MOP::Attribute::_process_accessors at line 320, avg 14µs/call # 57 times (364µs+0s) by Class::MOP::Attribute::_process_accessors at line 310, avg 6µs/call # 52 times (414µs+0s) by Class::MOP::Method::Accessor::_generate_reader_method_inline at line 155 of Class/MOP/Method/Accessor.pm, avg 8µs/call # 30 times (190µs+0s) by Class::MOP::Attribute::get_read_method_ref at line 184, avg 6µs/call # 23 times (322µs+0s) by Class::MOP::Method::Accessor::_generate_predicate_method_inline at line 190 of Class/MOP/Method/Accessor.pm, avg 14µs/call # 21 times (126µs+0s) by Moose::Meta::Method::Accessor::_inline_has at line 270 of Moose/Meta/Method/Accessor.pm, avg 6µs/call # 15 times (96µs+0s) by Class::MOP::Method::Accessor::_generate_accessor_method_inline at line 136 of Class/MOP/Method/Accessor.pm, avg 6µs/call # 14 times (80µs+0s) by Moose::Meta::Attribute::install_delegation at line 621 of Moose/Meta/Attribute.pm, avg 6µs/call # 14 times (72µs+0s) by Moose::Meta::Attribute::_make_delegation_method at line 725 of Moose/Meta/Attribute.pm, avg 5µs/call # 8 times (115µs+0s) by Class::MOP::Method::Accessor::_generate_clearer_method_inline at line 207 of Class/MOP/Method/Accessor.pm, avg 14µs/call # 5 times (30µs+0s) by Moose::Meta::Attribute::install_delegation at line 600 of Moose/Meta/Attribute.pm, avg 6µs/call # 3 times (19µs+0s) by Class::MOP::Method::Accessor::_generate_writer_method_inline at line 173 of Class/MOP/Method/Accessor.pm, avg 6µs/call # 2 times (8µs+0s) by Class::MOP::Attribute::remove_accessors at line 396, avg 4µs/call
sub associated_class { $_[0]->{'associated_class'} }
1601191.19ms
# spent 749µs within Class::MOP::Attribute::associated_methods which was called 119 times, avg 6µs/call: # 119 times (749µs+0s) by Moose::Meta::Attribute::_check_associated_methods at line 551 of Moose/Meta/Attribute.pm, avg 6µs/call
sub associated_methods { $_[0]->{'associated_methods'} }
161
162
# spent 2.74ms (1.75+985µs) within Class::MOP::Attribute::get_read_method which was called 54 times, avg 51µs/call: # 25 times (875µs+506µs) by Moose::Util::MetaRole::_make_new_metaclass at line 109 of Moose/Util/MetaRole.pm, avg 55µs/call # 15 times (535µs+359µs) by Class::MOP::Attribute::get_read_method_ref at line 184, avg 60µs/call # 14 times (344µs+119µs) by Moose::Meta::Method::Delegation::_get_delegate_accessor at line 125 of Moose/Meta/Method/Delegation.pm, avg 33µs/call
sub get_read_method {
1631942.55ms my $self = shift;
164 my $reader = $self->reader || $self->accessor;
# spent 665µs making 54 calls to Class::MOP::Mixin::AttributeCore::reader, avg 12µs/call # spent 320µs making 27 calls to Class::MOP::Mixin::AttributeCore::accessor, avg 12µs/call
165 # normal case ...
166 return $reader unless ref $reader;
167 # the HASH ref case
168 my ($name) = %$reader;
169 return $name;
170}
171
172sub get_write_method {
173 my $self = shift;
174 my $writer = $self->writer || $self->accessor;
175 # normal case ...
176 return $writer unless ref $writer;
177 # the HASH ref case
178 my ($name) = %$writer;
179 return $name;
180}
181
182
# spent 4.48ms (1.16+3.32) within Class::MOP::Attribute::get_read_method_ref which was called 15 times, avg 299µs/call: # 15 times (1.16ms+3.32ms) by MooseX::Emulate::Class::Accessor::Fast::mk_accessors at line 125 of MooseX/Emulate/Class/Accessor/Fast.pm, avg 299µs/call
sub get_read_method_ref {
18330544µs my $self = shift;
184 if ((my $reader = $self->get_read_method) && $self->associated_class) {
# spent 2.24ms making 15 calls to Class::MOP::Mixin::HasMethods::get_method, avg 149µs/call # spent 895µs making 15 calls to Class::MOP::Attribute::get_read_method, avg 60µs/call # spent 190µs making 30 calls to Class::MOP::Attribute::associated_class, avg 6µs/call
185 return $self->associated_class->get_method($reader);
186 }
187 else {
188 my $code = sub { $self->get_value(@_) };
189 if (my $class = $self->associated_class) {
190 return $class->method_metaclass->wrap(
191 $code,
192 package_name => $class->name,
193 name => '__ANON__'
194 );
195 }
196 else {
197 return $code;
198 }
199 }
200}
201
202sub get_write_method_ref {
203 my $self = shift;
204 if ((my $writer = $self->get_write_method) && $self->associated_class) {
205 return $self->associated_class->get_method($writer);
206 }
207 else {
208 my $code = sub { $self->set_value(@_) };
209 if (my $class = $self->associated_class) {
210 return $class->method_metaclass->wrap(
211 $code,
212 package_name => $class->name,
213 name => '__ANON__'
214 );
215 }
216 else {
217 return $code;
218 }
219 }
220}
221
222# slots
223
224129624.7ms12965.27ms
# spent 23.4ms (18.2+5.27) within Class::MOP::Attribute::slots which was called 1296 times, avg 18µs/call: # 1064 times (14.9ms+4.49ms) by Class::MOP::Instance::BUILDARGS at line 28 of Class/MOP/Instance.pm, avg 18µs/call # 105 times (1.49ms+342µs) by Moose::Meta::Method::Accessor::_inline_store at line 220 of Moose/Meta/Method/Accessor.pm, avg 17µs/call # 104 times (1.40ms+347µs) by Moose::Meta::Method::Accessor::_inline_get at line 254 of Moose/Meta/Method/Accessor.pm, avg 17µs/call # 21 times (346µs+81µs) by Moose::Meta::Method::Accessor::_inline_has at line 272 of Moose/Meta/Method/Accessor.pm, avg 20µs/call # 2 times (18µs+5µs) by Moose::Meta::Method::Accessor::_inline_store at line 221 of Moose/Meta/Method/Accessor.pm, avg 12µs/call
sub slots { (shift)->name }
# spent 5.27ms making 1296 calls to Class::MOP::Mixin::AttributeCore::name, avg 4µs/call
225
226# class association
227
228
# spent 12.2ms (8.31+3.90) within Class::MOP::Attribute::attach_to_class which was called 234 times, avg 52µs/call: # 234 times (8.31ms+3.90ms) by Class::MOP::Class::_attach_attribute at line 503 of Class/MOP/Class.pm, avg 52µs/call
sub attach_to_class {
22970212.5ms my ($self, $class) = @_;
230 (blessed($class) && $class->isa('Class::MOP::Class'))
# spent 1.33ms making 234 calls to Scalar::Util::blessed, avg 6µs/call # spent 1.13ms making 234 calls to UNIVERSAL::isa, avg 5µs/call
231 || confess "You must pass a Class::MOP::Class instance (or a subclass)";
232 weaken($self->{'associated_class'} = $class);
# spent 1.43ms making 234 calls to Scalar::Util::weaken, avg 6µs/call
233}
234
235
# spent 94µs within Class::MOP::Attribute::detach_from_class which was called 2 times, avg 47µs/call: # 2 times (94µs+0s) by Class::MOP::Class::remove_attribute at line 531 of Class/MOP/Class.pm, avg 47µs/call
sub detach_from_class {
2364101µs my $self = shift;
237 $self->{'associated_class'} = undef;
238}
239
240# method association
241
242
# spent 6.32ms within Class::MOP::Attribute::associate_method which was called 376 times, avg 17µs/call: # 305 times (5.20ms+0s) by Class::MOP::Attribute::_process_accessors at line 344, avg 17µs/call # 57 times (1.00ms+0s) by Class::MOP::Attribute::_process_accessors at line 316, avg 18µs/call # 14 times (113µs+0s) by Moose::Meta::Attribute::install_delegation at line 622 of Moose/Meta/Attribute.pm, avg 8µs/call
sub associate_method {
2437528.44ms my ($self, $method) = @_;
244 push @{$self->{'associated_methods'}} => $method;
245}
246
247## Slot management
248
249
# spent 2.43ms (763µs+1.67) within Class::MOP::Attribute::set_initial_value which was called 23 times, avg 106µs/call: # 21 times (685µs+1.41ms) by Moose::Meta::Attribute::initialize_instance_slot at line 400 of Moose/Meta/Attribute.pm, avg 100µs/call # 2 times (78µs+256µs) by Moose::Meta::Attribute::get_value at line 509 of Moose/Meta/Attribute.pm, avg 167µs/call
sub set_initial_value {
25046614µs my ($self, $instance, $value) = @_;
251 $self->_set_initial_slot_value(
# spent 991µs making 23 calls to Moose::Meta::Attribute::_set_initial_slot_value, avg 43µs/call # spent 427µs making 23 calls to Class::MOP::Class::initialize, avg 19µs/call # spent 136µs making 2 calls to Class::MOP::Class::Immutable::Moose::Meta::Class::get_meta_instance, avg 68µs/call # spent 114µs making 21 calls to Class::MOP::Class::get_meta_instance, avg 5µs/call
252 Class::MOP::Class->initialize(ref($instance))->get_meta_instance,
253 $instance,
254 $value
255 );
256}
257
2584416.46ms44160.4ms
# spent 70.8ms (10.4+60.4) within Class::MOP::Attribute::set_value which was called 441 times, avg 161µs/call: # 410 times (9.97ms+56.1ms) by Class::MOP::Class::_clone_instance at line 422 of Class/MOP/Class.pm, avg 161µs/call # 31 times (452µs+4.29ms) by Moose::Meta::Attribute::set_value at line 475 of Moose/Meta/Attribute.pm, avg 153µs/call
sub set_value { shift->set_raw_value(@_) }
# spent 60.4ms making 441 calls to Class::MOP::Attribute::set_raw_value, avg 137µs/call
2591151.56ms11515.8ms
# spent 17.4ms (1.64+15.8) within Class::MOP::Attribute::get_value which was called 115 times, avg 152µs/call: # 87 times (1.43ms+13.5ms) by Moose::Meta::Attribute::get_value at line 534 of Moose/Meta/Attribute.pm, avg 172µs/call # 22 times (131µs+1.32ms) by Moose::Meta::Attribute::clone at line 245 of Moose/Meta/Attribute.pm, avg 66µs/call # 6 times (79µs+940µs) by Moose::Meta::Mixin::AttributeCore::is_lazy or Moose::Meta::Mixin::AttributeCore::should_auto_deref or Moose::Meta::Mixin::AttributeCore::type_constraint at line 104 of Class/MOP/Method/Accessor.pm, avg 170µs/call
sub get_value { shift->get_raw_value(@_) }
# spent 15.8ms making 115 calls to Class::MOP::Attribute::get_raw_value, avg 137µs/call
260
261
# spent 60.4ms (18.9+41.5) within Class::MOP::Attribute::set_raw_value which was called 441 times, avg 137µs/call: # 441 times (18.9ms+41.5ms) by Class::MOP::Attribute::set_value at line 258, avg 137µs/call
sub set_raw_value {
26288219.3ms my ($self, $instance, $value) = @_;
263
264 Class::MOP::Class->initialize(ref($instance))
# spent 18.9ms making 404 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance, avg 47µs/call # spent 13.9ms making 441 calls to Class::MOP::Class::initialize, avg 32µs/call # spent 5.01ms making 441 calls to Class::MOP::Instance::set_slot_value, avg 11µs/call # spent 2.20ms making 441 calls to Class::MOP::Mixin::AttributeCore::name, avg 5µs/call # spent 1.40ms making 27 calls to Class::MOP::Class::Immutable::Class::MOP::Class::__ANON__::SERIAL::5::get_meta_instance, avg 52µs/call # spent 82µs making 10 calls to Class::MOP::Class::get_meta_instance, avg 8µs/call
265 ->get_meta_instance
266 ->set_slot_value($instance, $self->name, $value);
267}
268
269
# spent 15.8ms (6.25+9.57) within Class::MOP::Attribute::get_raw_value which was called 115 times, avg 137µs/call: # 115 times (6.25ms+9.57ms) by Class::MOP::Attribute::get_value at line 259, avg 137µs/call
sub get_raw_value {
2702305.71ms my ($self, $instance) = @_;
271
272 Class::MOP::Class->initialize(ref($instance))
# spent 3.47ms making 63 calls to Class::MOP::Class::Immutable::Class::MOP::Class::__ANON__::SERIAL::5::get_meta_instance, avg 55µs/call # spent 3.46ms making 115 calls to Class::MOP::Class::initialize, avg 30µs/call # spent 1.02ms making 115 calls to Class::MOP::Instance::get_slot_value, avg 9µs/call # spent 762µs making 115 calls to Class::MOP::Mixin::AttributeCore::name, avg 7µs/call # spent 599µs making 25 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance, avg 24µs/call # spent 211µs making 25 calls to Class::MOP::Class::get_meta_instance, avg 8µs/call # spent 49µs making 2 calls to Class::MOP::Class::Immutable::Moose::Meta::Class::get_meta_instance, avg 25µs/call
273 ->get_meta_instance
274 ->get_slot_value($instance, $self->name);
275}
276
277
# spent 4.22ms (1.44+2.77) within Class::MOP::Attribute::has_value which was called 60 times, avg 70µs/call: # 56 times (1.17ms+2.44ms) by Moose::Meta::Attribute::clone at line 241 of Moose/Meta/Attribute.pm, avg 64µs/call # 2 times (200µs+197µs) by Moose::Meta::Mixin::AttributeCore::has_handles at line 119 of Class/MOP/Method/Accessor.pm, avg 199µs/call # 2 times (75µs+139µs) by Moose::Meta::Attribute::get_value at line 499 of Moose/Meta/Attribute.pm, avg 107µs/call
sub has_value {
2781201.41ms my ($self, $instance) = @_;
279
280 Class::MOP::Class->initialize(ref($instance))
# spent 1.32ms making 57 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance, avg 23µs/call # spent 908µs making 60 calls to Class::MOP::Class::initialize, avg 15µs/call # spent 313µs making 60 calls to Class::MOP::Instance::is_slot_initialized, avg 5µs/call # spent 151µs making 60 calls to Class::MOP::Mixin::AttributeCore::name, avg 3µs/call # spent 72µs making 2 calls to Class::MOP::Class::Immutable::Moose::Meta::Class::get_meta_instance, avg 36µs/call # spent 10µs making 1 call to Class::MOP::Class::get_meta_instance
281 ->get_meta_instance
282 ->is_slot_initialized($instance, $self->name);
283}
284
285sub clear_value {
286 my ($self, $instance) = @_;
287
288 Class::MOP::Class->initialize(ref($instance))
289 ->get_meta_instance
290 ->deinitialize_slot($instance, $self->name);
291}
292
293## load em up ...
294
2952233.00ms
# spent 1.31ms within Class::MOP::Attribute::accessor_metaclass which was called 223 times, avg 6µs/call: # 166 times (960µs+0s) by Class::MOP::Attribute::__ANON__[/usr/lib/perl5/vendor_perl/5.10.1/i386-linux-thread-multi/Class/MOP/Attribute.pm:340] at line 332, avg 6µs/call # 57 times (347µs+0s) by Class::MOP::Attribute::_process_accessors at line 310, avg 6µs/call
sub accessor_metaclass { 'Class::MOP::Method::Accessor' }
296
297
# spent 587ms (47.9+539) within Class::MOP::Attribute::_process_accessors which was called 362 times, avg 1.62ms/call: # 148 times (20.8ms+92.1ms) by Class::MOP::Attribute::install_accessors at line 358, avg 763µs/call # 139 times (17.4ms+391ms) by Moose::Meta::Attribute::_process_accessors at line 578 of Moose/Meta/Attribute.pm, avg 2.94ms/call # 36 times (4.94ms+21.0ms) by Class::MOP::Attribute::install_accessors at line 366, avg 719µs/call # 31 times (3.96ms+30.4ms) by Class::MOP::Attribute::install_accessors at line 354, avg 1.11ms/call # 8 times (838µs+4.72ms) by Class::MOP::Attribute::install_accessors at line 362, avg 694µs/call
sub _process_accessors {
298325842.4ms my ($self, $type, $accessor, $generate_as_inline_methods) = @_;
299
300 my $method_ctx;
301
302 if ( my $ctx = $self->definition_context ) {
# spent 2.70ms making 362 calls to Class::MOP::Mixin::AttributeCore::definition_context, avg 7µs/call
303 $method_ctx = { %$ctx };
304 }
305
306 if (ref($accessor)) {
307 (ref($accessor) eq 'HASH')
308 || confess "bad accessor/reader/writer/predicate/clearer format, must be a HASH ref";
309 my ($name, $method) = %{$accessor};
310 $method = $self->accessor_metaclass->wrap(
# spent 10.9ms making 57 calls to Class::MOP::Method::wrap, avg 191µs/call # spent 364µs making 57 calls to Class::MOP::Attribute::associated_class, avg 6µs/call # spent 347µs making 57 calls to Class::MOP::Attribute::accessor_metaclass, avg 6µs/call # spent 328µs making 57 calls to Class::MOP::Package::name, avg 6µs/call
311 $method,
312 package_name => $self->associated_class->name,
313 name => $name,
314 definition_context => $method_ctx,
315 );
316 $self->associate_method($method);
# spent 1.00ms making 57 calls to Class::MOP::Attribute::associate_method, avg 18µs/call
317 return ($name, $method);
318 }
319 else {
320 my $inline_me = ($generate_as_inline_methods && $self->associated_class->instance_metaclass->is_inlinable);
# spent 1.15ms making 84 calls to Class::MOP::Attribute::associated_class, avg 14µs/call # spent 686µs making 84 calls to Class::MOP::Instance::is_inlinable, avg 8µs/call # spent 607µs making 84 calls to Class::MOP::Class::instance_metaclass, avg 7µs/call
321 my $method;
322
# spent 481ms (21.1+460) within Class::MOP::Attribute::__ANON__[/usr/lib/perl5/vendor_perl/5.10.1/i386-linux-thread-multi/Class/MOP/Attribute.pm:340] which was called 305 times, avg 1.58ms/call: # 305 times (21.1ms+460ms) by Try::Tiny::try at line 76 of Try/Tiny.pm, avg 1.58ms/call
try {
32397619.0ms if ( $method_ctx ) {
324 my $desc = "accessor $accessor";
325 if ( $accessor ne $self->name ) {
# spent 570µs making 141 calls to Class::MOP::Mixin::AttributeCore::name, avg 4µs/call
326 $desc .= " of attribute " . $self->name;
327 }
328
329 $method_ctx->{description} = $desc;
330 }
331
332 $method = $self->accessor_metaclass->new(
# spent 453ms making 305 calls to Class::MOP::Method::Accessor::new, avg 1.49ms/call # spent 2.35ms making 305 calls to Class::MOP::Attribute::associated_class, avg 8µs/call # spent 1.57ms making 305 calls to Class::MOP::Package::name, avg 5µs/call # spent 960µs making 166 calls to Class::MOP::Attribute::accessor_metaclass, avg 6µs/call # spent 935µs making 122 calls to Moose::Meta::Attribute::accessor_metaclass, avg 8µs/call # spent 162µs making 17 calls to MooseX::Emulate::Class::Accessor::Fast::Meta::Role::Attribute::accessor_metaclass, avg 10µs/call
333 attribute => $self,
334 is_inline => $inline_me,
335 accessor_type => $type,
336 package_name => $self->associated_class->name,
337 name => $accessor,
338 definition_context => $method_ctx,
339 );
340 }
341 catch {
342 confess "Could not create the '$type' method for " . $self->name . " because : $_";
343 };
# spent 510ms making 305 calls to Try::Tiny::try, avg 1.67ms/call, recursion: max depth 3, time 421ms # spent 5.74ms making 305 calls to Try::Tiny::catch, avg 19µs/call
344 $self->associate_method($method);
# spent 5.20ms making 305 calls to Class::MOP::Attribute::associate_method, avg 17µs/call
345 return ($accessor, $method);
346 }
347}
348
349
# spent 784ms (41.0+743) within Class::MOP::Attribute::install_accessors which was called 302 times, avg 2.60ms/call: # 121 times (15.4ms+490ms) by Moose::Meta::Attribute::install_accessors at line 544 of Moose/Meta/Attribute.pm, avg 4.17ms/call # 114 times (16.4ms+120ms) by Class::MOP::Class::__ANON__[/usr/lib/perl5/vendor_perl/5.10.1/i386-linux-thread-multi/Class/MOP/Class.pm:515] at line 514 of Class/MOP/Class.pm, avg 1.19ms/call # 67 times (9.16ms+134ms) by Class::MOP::Class::_inline_accessors at line 1030 of Class/MOP/Class.pm, avg 2.14ms/call
sub install_accessors {
350271833.0ms my $self = shift;
351 my $inline = shift;
352 my $class = $self->associated_class;
# spent 2.49ms making 302 calls to Class::MOP::Attribute::associated_class, avg 8µs/call
353
354 $class->add_method(
# spent 340ms making 101 calls to Moose::Meta::Attribute::_process_accessors, avg 3.37ms/call # spent 39.3ms making 132 calls to Class::MOP::Mixin::HasMethods::add_method, avg 298µs/call # spent 34.4ms making 31 calls to Class::MOP::Attribute::_process_accessors, avg 1.11ms/call # spent 2.80ms making 302 calls to Class::MOP::Mixin::AttributeCore::has_accessor, avg 9µs/call # spent 941µs making 132 calls to Class::MOP::Mixin::AttributeCore::accessor, avg 7µs/call
355 $self->_process_accessors('accessor' => $self->accessor(), $inline)
356 ) if $self->has_accessor();
357
358 $class->add_method(
# spent 113ms making 148 calls to Class::MOP::Attribute::_process_accessors, avg 763µs/call # spent 80.0ms making 20 calls to Moose::Meta::Attribute::_process_accessors, avg 4.00ms/call # spent 46.4ms making 168 calls to Class::MOP::Mixin::HasMethods::add_method, avg 276µs/call # spent 2.99ms making 302 calls to Class::MOP::Mixin::AttributeCore::has_reader, avg 10µs/call # spent 1.89ms making 168 calls to Class::MOP::Mixin::AttributeCore::reader, avg 11µs/call
359 $self->_process_accessors('reader' => $self->reader(), $inline)
360 ) if $self->has_reader();
361
362 $class->add_method(
# spent 5.56ms making 8 calls to Class::MOP::Attribute::_process_accessors, avg 694µs/call # spent 2.99ms making 302 calls to Class::MOP::Mixin::AttributeCore::has_writer, avg 10µs/call # spent 1.92ms making 8 calls to Class::MOP::Mixin::HasMethods::add_method, avg 240µs/call # spent 196µs making 8 calls to Class::MOP::Mixin::AttributeCore::writer, avg 25µs/call
363 $self->_process_accessors('writer' => $self->writer(), $inline)
364 ) if $self->has_writer();
365
366 $class->add_method(
# spent 25.9ms making 36 calls to Class::MOP::Attribute::_process_accessors, avg 719µs/call # spent 12.8ms making 46 calls to Class::MOP::Mixin::HasMethods::add_method, avg 279µs/call # spent 12.3ms making 10 calls to Moose::Meta::Attribute::_process_accessors, avg 1.23ms/call # spent 2.30ms making 302 calls to Class::MOP::Mixin::AttributeCore::has_predicate, avg 8µs/call # spent 319µs making 46 calls to Class::MOP::Mixin::AttributeCore::predicate, avg 7µs/call
367 $self->_process_accessors('predicate' => $self->predicate(), $inline)
368 ) if $self->has_predicate();
369
370 $class->add_method(
# spent 10.1ms making 8 calls to Moose::Meta::Attribute::_process_accessors, avg 1.26ms/call # spent 2.24ms making 302 calls to Class::MOP::Mixin::AttributeCore::has_clearer, avg 7µs/call # spent 2.16ms making 8 calls to Class::MOP::Mixin::HasMethods::add_method, avg 270µs/call # spent 166µs making 8 calls to Class::MOP::Mixin::AttributeCore::clearer, avg 21µs/call
371 $self->_process_accessors('clearer' => $self->clearer(), $inline)
372 ) if $self->has_clearer();
373
374 return;
375}
376
377{
37814µs
# spent 1.10ms (78µs+1.02) within Class::MOP::Attribute::__ANON__[/usr/lib/perl5/vendor_perl/5.10.1/i386-linux-thread-multi/Class/MOP/Attribute.pm:386] which was called 2 times, avg 550µs/call: # 2 times (78µs+1.02ms) by Class::MOP::Attribute::remove_accessors at line 396, avg 550µs/call
my $_remove_accessor = sub {
3798111µs my ($accessor, $class) = @_;
380 if (ref($accessor) && ref($accessor) eq 'HASH') {
381 ($accessor) = keys %{$accessor};
382 }
383 my $method = $class->get_method($accessor);
# spent 190µs making 2 calls to Class::MOP::Mixin::HasMethods::get_method, avg 95µs/call
384 $class->remove_method($accessor)
# spent 827µs making 2 calls to Class::MOP::Mixin::HasMethods::remove_method, avg 413µs/call # spent 5µs making 2 calls to UNIVERSAL::isa, avg 2µs/call
385 if (ref($method) && $method->isa('Class::MOP::Method::Accessor'));
386111µs };
387
388
# spent 1.32ms (157µs+1.17) within Class::MOP::Attribute::remove_accessors which was called 2 times, avg 662µs/call: # 2 times (157µs+1.17ms) by Moose::Meta::Attribute::remove_accessors at line 583 of Moose/Meta/Attribute.pm, avg 662µs/call
sub remove_accessors {
3891491µs my $self = shift;
390 # TODO:
391 # we really need to make sure to remove from the
392 # associates methods here as well. But this is
393 # such a slimly used method, I am not worried
394 # about it right now.
395 $_remove_accessor->($self->accessor(), $self->associated_class()) if $self->has_accessor();
# spent 9µs making 2 calls to Class::MOP::Mixin::AttributeCore::has_accessor, avg 5µs/call
396 $_remove_accessor->($self->reader(), $self->associated_class()) if $self->has_reader();
# spent 1.10ms making 2 calls to Class::MOP::Attribute::__ANON__[Class/MOP/Attribute.pm:386], avg 550µs/call # spent 10µs making 2 calls to Class::MOP::Mixin::AttributeCore::has_reader, avg 5µs/call # spent 8µs making 2 calls to Class::MOP::Mixin::AttributeCore::reader, avg 4µs/call # spent 8µs making 2 calls to Class::MOP::Attribute::associated_class, avg 4µs/call
397 $_remove_accessor->($self->writer(), $self->associated_class()) if $self->has_writer();
# spent 14µs making 2 calls to Class::MOP::Mixin::AttributeCore::has_writer, avg 7µs/call
398 $_remove_accessor->($self->predicate(), $self->associated_class()) if $self->has_predicate();
# spent 9µs making 2 calls to Class::MOP::Mixin::AttributeCore::has_predicate, avg 5µs/call
399 $_remove_accessor->($self->clearer(), $self->associated_class()) if $self->has_clearer();
# spent 8µs making 2 calls to Class::MOP::Mixin::AttributeCore::has_clearer, avg 4µs/call
400 return;
401 }
402
403}
404
405113µs1;
406
407__END__
408
409=pod
410
411=head1 NAME
412
413Class::MOP::Attribute - Attribute Meta Object
414
415=head1 SYNOPSIS
416
417 Class::MOP::Attribute->new(
418 foo => (
419 accessor => 'foo', # dual purpose get/set accessor
420 predicate => 'has_foo', # predicate check for defined-ness
421 init_arg => '-foo', # class->new will look for a -foo key
422 default => 'BAR IS BAZ!' # if no -foo key is provided, use this
423 )
424 );
425
426 Class::MOP::Attribute->new(
427 bar => (
428 reader => 'bar', # getter
429 writer => 'set_bar', # setter
430 predicate => 'has_bar', # predicate check for defined-ness
431 init_arg => ':bar', # class->new will look for a :bar key
432 # no default value means it is undef
433 )
434 );
435
436=head1 DESCRIPTION
437
438The Attribute Protocol is almost entirely an invention of
439C<Class::MOP>. Perl 5 does not have a consistent notion of
440attributes. There are so many ways in which this is done, and very few
441(if any) are easily discoverable by this module.
442
443With that said, this module attempts to inject some order into this
444chaos, by introducing a consistent API which can be used to create
445object attributes.
446
447=head1 METHODS
448
449=head2 Creation
450
451=over 4
452
453=item B<< Class::MOP::Attribute->new($name, ?%options) >>
454
455An attribute must (at the very least), have a C<$name>. All other
456C<%options> are added as key-value pairs.
457
458=over 8
459
460=item * init_arg
461
462This is a string value representing the expected key in an
463initialization hash. For instance, if we have an C<init_arg> value of
464C<-foo>, then the following code will Just Work.
465
466 MyClass->meta->new_object( -foo => 'Hello There' );
467
468If an init_arg is not assigned, it will automatically use the
469attribute's name. If C<init_arg> is explicitly set to C<undef>, the
470attribute cannot be specified during initialization.
471
472=item * builder
473
474This provides the name of a method that will be called to initialize
475the attribute. This method will be called on the object after it is
476constructed. It is expected to return a valid value for the attribute.
477
478=item * default
479
480This can be used to provide an explicit default for initializing the
481attribute. If the default you provide is a subroutine reference, then
482this reference will be called I<as a method> on the object.
483
484If the value is a simple scalar (string or number), then it can be
485just passed as is. However, if you wish to initialize it with a HASH
486or ARRAY ref, then you need to wrap that inside a subroutine
487reference:
488
489 Class::MOP::Attribute->new(
490 'foo' => (
491 default => sub { [] },
492 )
493 );
494
495 # or ...
496
497 Class::MOP::Attribute->new(
498 'foo' => (
499 default => sub { {} },
500 )
501 );
502
503If you wish to initialize an attribute with a subroutine reference
504itself, then you need to wrap that in a subroutine as well:
505
506 Class::MOP::Attribute->new(
507 'foo' => (
508 default => sub {
509 sub { print "Hello World" }
510 },
511 )
512 );
513
514And lastly, if the value of your attribute is dependent upon some
515other aspect of the instance structure, then you can take advantage of
516the fact that when the C<default> value is called as a method:
517
518 Class::MOP::Attribute->new(
519 'object_identity' => (
520 default => sub { Scalar::Util::refaddr( $_[0] ) },
521 )
522 );
523
524Note that there is no guarantee that attributes are initialized in any
525particular order, so you cannot rely on the value of some other
526attribute when generating the default.
527
528=item * initializer
529
530This option can be either a method name or a subroutine
531reference. This method will be called when setting the attribute's
532value in the constructor. Unlike C<default> and C<builder>, the
533initializer is only called when a value is provided to the
534constructor. The initializer allows you to munge this value during
535object construction.
536
537The initializer is called as a method with three arguments. The first
538is the value that was passed to the constructor. The second is a
539subroutine reference that can be called to actually set the
540attribute's value, and the last is the associated
541C<Class::MOP::Attribute> object.
542
543This contrived example shows an initializer that sets the attribute to
544twice the given value.
545
546 Class::MOP::Attribute->new(
547 'doubled' => (
548 initializer => sub {
549 my ( $self, $value, $set, $attr ) = @_;
550 $set->( $value * 2 );
551 },
552 )
553 );
554
555Since an initializer can be a method name, you can easily make
556attribute initialization use the writer:
557
558 Class::MOP::Attribute->new(
559 'some_attr' => (
560 writer => 'some_attr',
561 initializer => 'some_attr',
562 )
563 );
564
565Your writer will need to examine C<@_> and determine under which
566context it is being called.
567
568=back
569
570The C<accessor>, C<reader>, C<writer>, C<predicate> and C<clearer>
571options all accept the same parameters. You can provide the name of
572the method, in which case an appropriate default method will be
573generated for you. Or instead you can also provide hash reference
574containing exactly one key (the method name) and one value. The value
575should be a subroutine reference, which will be installed as the
576method itself.
577
578=over 8
579
580=item * accessor
581
582An C<accessor> is a standard Perl-style read/write accessor. It will
583return the value of the attribute, and if a value is passed as an
584argument, it will assign that value to the attribute.
585
586Note that C<undef> is a legitimate value, so this will work:
587
588 $object->set_something(undef);
589
590=item * reader
591
592This is a basic read-only accessor. It returns the value of the
593attribute.
594
595=item * writer
596
597This is a basic write accessor, it accepts a single argument, and
598assigns that value to the attribute.
599
600Note that C<undef> is a legitimate value, so this will work:
601
602 $object->set_something(undef);
603
604=item * predicate
605
606The predicate method returns a boolean indicating whether or not the
607attribute has been explicitly set.
608
609Note that the predicate returns true even if the attribute was set to
610a false value (C<0> or C<undef>).
611
612=item * clearer
613
614This method will uninitialize the attribute. After an attribute is
615cleared, its C<predicate> will return false.
616
617=item * definition_context
618
619Mostly, this exists as a hook for the benefit of Moose.
620
621This option should be a hash reference containing several keys which
622will be used when inlining the attribute's accessors. The keys should
623include C<line>, the line number where the attribute was created, and
624either C<file> or C<description>.
625
626This information will ultimately be used when eval'ing inlined
627accessor code so that error messages report a useful line and file
628name.
629
630=back
631
632=item B<< $attr->clone(%options) >>
633
634This clones the attribute. Any options you provide will override the
635settings of the original attribute. You can change the name of the new
636attribute by passing a C<name> key in C<%options>.
637
638=back
639
640=head2 Informational
641
642These are all basic read-only accessors for the values passed into
643the constructor.
644
645=over 4
646
647=item B<< $attr->name >>
648
649Returns the attribute's name.
650
651=item B<< $attr->accessor >>
652
653=item B<< $attr->reader >>
654
655=item B<< $attr->writer >>
656
657=item B<< $attr->predicate >>
658
659=item B<< $attr->clearer >>
660
661The C<accessor>, C<reader>, C<writer>, C<predicate>, and C<clearer>
662methods all return exactly what was passed to the constructor, so it
663can be either a string containing a method name, or a hash reference.
664
665=item B<< $attr->initializer >>
666
667Returns the initializer as passed to the constructor, so this may be
668either a method name or a subroutine reference.
669
670=item B<< $attr->init_arg >>
671
672=item B<< $attr->is_default_a_coderef >>
673
674=item B<< $attr->default($instance) >>
675
676The C<$instance> argument is optional. If you don't pass it, the
677return value for this method is exactly what was passed to the
678constructor, either a simple scalar or a subroutine reference.
679
680If you I<do> pass an C<$instance> and the default is a subroutine
681reference, then the reference is called as a method on the
682C<$instance> and the generated value is returned.
683
684=item B<< $attr->slots >>
685
686Return a list of slots required by the attribute. This is usually just
687one, the name of the attribute.
688
689A slot is the name of the hash key used to store the attribute in an
690object instance.
691
692=item B<< $attr->get_read_method >>
693
694=item B<< $attr->get_write_method >>
695
696Returns the name of a method suitable for reading or writing the value
697of the attribute in the associated class.
698
699If an attribute is read- or write-only, then these methods can return
700C<undef> as appropriate.
701
702=item B<< $attr->has_read_method >>
703
704=item B<< $attr->has_write_method >>
705
706This returns a boolean indicating whether the attribute has a I<named>
707read or write method.
708
709=item B<< $attr->get_read_method_ref >>
710
711=item B<< $attr->get_write_method_ref >>
712
713Returns the subroutine reference of a method suitable for reading or
714writing the attribute's value in the associated class. These methods
715always return a subroutine reference, regardless of whether or not the
716attribute is read- or write-only.
717
718=item B<< $attr->insertion_order >>
719
720If this attribute has been inserted into a class, this returns a zero
721based index regarding the order of insertion.
722
723=back
724
725=head2 Informational predicates
726
727These are all basic predicate methods for the values passed into C<new>.
728
729=over 4
730
731=item B<< $attr->has_accessor >>
732
733=item B<< $attr->has_reader >>
734
735=item B<< $attr->has_writer >>
736
737=item B<< $attr->has_predicate >>
738
739=item B<< $attr->has_clearer >>
740
741=item B<< $attr->has_initializer >>
742
743=item B<< $attr->has_init_arg >>
744
745This will be I<false> if the C<init_arg> was set to C<undef>.
746
747=item B<< $attr->has_default >>
748
749This will be I<false> if the C<default> was set to C<undef>, since
750C<undef> is the default C<default> anyway.
751
752=item B<< $attr->has_builder >>
753
754=item B<< $attr->has_insertion_order >>
755
756This will be I<false> if this attribute has not be inserted into a class
757
758=back
759
760=head2 Value management
761
762These methods are basically "back doors" to the instance, and can be
763used to bypass the regular accessors, but still stay within the MOP.
764
765These methods are not for general use, and should only be used if you
766really know what you are doing.
767
768=over 4
769
770=item B<< $attr->initialize_instance_slot($meta_instance, $instance, $params) >>
771
772This method is used internally to initialize the attribute's slot in
773the object C<$instance>.
774
775The C<$params> is a hash reference of the values passed to the object
776constructor.
777
778It's unlikely that you'll need to call this method yourself.
779
780=item B<< $attr->set_value($instance, $value) >>
781
782Sets the value without going through the accessor. Note that this
783works even with read-only attributes.
784
785=item B<< $attr->set_raw_value($instance, $value) >>
786
787Sets the value with no side effects such as a trigger.
788
789This doesn't actually apply to Class::MOP attributes, only to subclasses.
790
791=item B<< $attr->set_initial_value($instance, $value) >>
792
793Sets the value without going through the accessor. This method is only
794called when the instance is first being initialized.
795
796=item B<< $attr->get_value($instance) >>
797
798Returns the value without going through the accessor. Note that this
799works even with write-only accessors.
800
801=item B<< $attr->get_raw_value($instance) >>
802
803Returns the value without any side effects such as lazy attributes.
804
805Doesn't actually apply to Class::MOP attributes, only to subclasses.
806
807=item B<< $attr->has_value($instance) >>
808
809Return a boolean indicating whether the attribute has been set in
810C<$instance>. This how the default C<predicate> method works.
811
812=item B<< $attr->clear_value($instance) >>
813
814This will clear the attribute's value in C<$instance>. This is what
815the default C<clearer> calls.
816
817Note that this works even if the attribute does not have any
818associated read, write or clear methods.
819
820=back
821
822=head2 Class association
823
824These methods allow you to manage the attributes association with
825the class that contains it. These methods should not be used
826lightly, nor are they very magical, they are mostly used internally
827and by metaclass instances.
828
829=over 4
830
831=item B<< $attr->associated_class >>
832
833This returns the C<Class::MOP::Class> with which this attribute is
834associated, if any.
835
836=item B<< $attr->attach_to_class($metaclass) >>
837
838This method stores a weakened reference to the C<$metaclass> object
839internally.
840
841This method does not remove the attribute from its old class,
842nor does it create any accessors in the new class.
843
844It is probably best to use the L<Class::MOP::Class> C<add_attribute>
845method instead.
846
847=item B<< $attr->detach_from_class >>
848
849This method removes the associate metaclass object from the attribute
850it has one.
851
852This method does not remove the attribute itself from the class, or
853remove its accessors.
854
855It is probably best to use the L<Class::MOP::Class>
856C<remove_attribute> method instead.
857
858=back
859
860=head2 Attribute Accessor generation
861
862=over 4
863
864=item B<< $attr->accessor_metaclass >>
865
866Accessor methods are generated using an accessor metaclass. By
867default, this is L<Class::MOP::Method::Accessor>. This method returns
868the name of the accessor metaclass that this attribute uses.
869
870=item B<< $attr->associate_method($method) >>
871
872This associates a L<Class::MOP::Method> object with the
873attribute. Typically, this is called internally when an attribute
874generates its accessors.
875
876=item B<< $attr->associated_methods >>
877
878This returns the list of methods which have been associated with the
879attribute.
880
881=item B<< $attr->install_accessors >>
882
883This method generates and installs code the attributes various
884accessors. It is typically called from the L<Class::MOP::Class>
885C<add_attribute> method.
886
887=item B<< $attr->remove_accessors >>
888
889This method removes all of the accessors associated with the
890attribute.
891
892This does not currently remove methods from the list returned by
893C<associated_methods>.
894
895=back
896
897=head2 Introspection
898
899=over 4
900
901=item B<< Class::MOP::Attribute->meta >>
902
903This will return a L<Class::MOP::Class> instance for this class.
904
905It should also be noted that L<Class::MOP> will actually bootstrap
906this module by installing a number of attribute meta-objects into its
907metaclass.
908
909=back
910
911=head1 AUTHORS
912
913Stevan Little E<lt>stevan@iinteractive.comE<gt>
914
915=head1 COPYRIGHT AND LICENSE
916
917Copyright 2006-2010 by Infinity Interactive, Inc.
918
919L<http://www.iinteractive.com>
920
921This library is free software; you can redistribute it and/or modify
922it under the same terms as Perl itself.
923
924=cut
925
926