File | /usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Class/MOP/Attribute.pm |
Statements Executed | 19359 |
Statement Execution Time | 42.8ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
333 | 5 | 2 | 7.48ms | 94.8ms | _process_accessors | Class::MOP::Attribute::
270 | 3 | 2 | 6.63ms | 124ms | install_accessors | Class::MOP::Attribute::
664 | 1 | 1 | 4.62ms | 7.33ms | _set_initial_slot_value | Class::MOP::Attribute::
1810 | 6 | 3 | 4.12ms | 4.84ms | slots | Class::MOP::Attribute::
784 | 1 | 1 | 3.95ms | 14.8ms | initialize_instance_slot | Class::MOP::Attribute::
276 | 1 | 1 | 3.34ms | 80.3ms | __ANON__[:340] | Class::MOP::Attribute::
202 | 50 | 4 | 3.01ms | 9.74ms | new | Class::MOP::Attribute::
335 | 1 | 1 | 2.99ms | 10.4ms | set_initial_value | Class::MOP::Attribute::
290 | 1 | 1 | 2.47ms | 6.60ms | set_raw_value | Class::MOP::Attribute::
202 | 2 | 2 | 1.43ms | 1.87ms | attach_to_class | Class::MOP::Attribute::
1126 | 22 | 7 | 1.16ms | 1.16ms | associated_class | Class::MOP::Attribute::
115 | 1 | 1 | 960µs | 1.60ms | _new | Class::MOP::Attribute::
342 | 3 | 2 | 873µs | 873µs | associate_method | Class::MOP::Attribute::
290 | 1 | 1 | 712µs | 7.31ms | set_value | Class::MOP::Attribute::
31 | 2 | 2 | 463µs | 2.41ms | get_read_method_ref | Class::MOP::Attribute::
31 | 1 | 1 | 302µs | 425µs | get_read_method | Class::MOP::Attribute::
223 | 2 | 1 | 196µs | 196µs | accessor_metaclass | Class::MOP::Attribute::
86 | 1 | 1 | 106µs | 106µs | associated_methods | Class::MOP::Attribute::
6 | 1 | 1 | 62µs | 142µs | get_raw_value | Class::MOP::Attribute::
2 | 1 | 1 | 44µs | 137µs | get_write_method_ref | Class::MOP::Attribute::
2 | 1 | 1 | 28µs | 57µs | has_value | Class::MOP::Attribute::
2 | 1 | 1 | 24µs | 32µs | get_write_method | Class::MOP::Attribute::
6 | 1 | 1 | 19µs | 161µs | get_value | Class::MOP::Attribute::
1 | 1 | 1 | 14µs | 18µs | BEGIN@4 | Class::MOP::Attribute::
1 | 1 | 1 | 8µs | 76µs | BEGIN@17 | Class::MOP::Attribute::
1 | 1 | 1 | 7µs | 32µs | BEGIN@10 | Class::MOP::Attribute::
1 | 1 | 1 | 7µs | 34µs | BEGIN@11 | Class::MOP::Attribute::
1 | 1 | 1 | 7µs | 32µs | BEGIN@9 | Class::MOP::Attribute::
1 | 1 | 1 | 7µs | 16µs | BEGIN@5 | Class::MOP::Attribute::
1 | 1 | 1 | 4µs | 4µs | BEGIN@7 | Class::MOP::Attribute::
0 | 0 | 0 | 0s | 0s | __ANON__[:151] | Class::MOP::Attribute::
0 | 0 | 0 | 0s | 0s | __ANON__[:188] | Class::MOP::Attribute::
0 | 0 | 0 | 0s | 0s | __ANON__[:208] | Class::MOP::Attribute::
0 | 0 | 0 | 0s | 0s | __ANON__[:343] | Class::MOP::Attribute::
0 | 0 | 0 | 0s | 0s | __ANON__[:386] | Class::MOP::Attribute::
0 | 0 | 0 | 0s | 0s | clear_value | Class::MOP::Attribute::
0 | 0 | 0 | 0s | 0s | clone | Class::MOP::Attribute::
0 | 0 | 0 | 0s | 0s | detach_from_class | Class::MOP::Attribute::
0 | 0 | 0 | 0s | 0s | remove_accessors | Class::MOP::Attribute::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | |||||
2 | package Class::MOP::Attribute; | ||||
3 | |||||
4 | 3 | 20µs | 2 | 21µs | # spent 18µs (14+3) within Class::MOP::Attribute::BEGIN@4 which was called
# once (14µs+3µs) by Class::MOP::BEGIN@19 at line 4 # spent 18µs making 1 call to Class::MOP::Attribute::BEGIN@4
# spent 3µs making 1 call to strict::import |
5 | 3 | 19µs | 2 | 25µs | # spent 16µs (7+9) within Class::MOP::Attribute::BEGIN@5 which was called
# once (7µs+9µs) by Class::MOP::BEGIN@19 at line 5 # spent 16µs making 1 call to Class::MOP::Attribute::BEGIN@5
# spent 9µs making 1 call to warnings::import |
6 | |||||
7 | 3 | 19µs | 1 | 4µs | # spent 4µs within Class::MOP::Attribute::BEGIN@7 which was called
# once (4µs+0s) by Class::MOP::BEGIN@19 at line 7 # spent 4µs making 1 call to Class::MOP::Attribute::BEGIN@7 |
8 | |||||
9 | 3 | 24µs | 2 | 57µs | # spent 32µs (7+25) within Class::MOP::Attribute::BEGIN@9 which was called
# once (7µs+25µs) by Class::MOP::BEGIN@19 at line 9 # spent 32µs making 1 call to Class::MOP::Attribute::BEGIN@9
# spent 25µs making 1 call to Exporter::import |
10 | 3 | 21µs | 2 | 57µs | # spent 32µs (7+25) within Class::MOP::Attribute::BEGIN@10 which was called
# once (7µs+25µs) by Class::MOP::BEGIN@19 at line 10 # spent 32µs making 1 call to Class::MOP::Attribute::BEGIN@10
# spent 25µs making 1 call to Exporter::import |
11 | 3 | 55µs | 2 | 61µs | # spent 34µs (7+27) within Class::MOP::Attribute::BEGIN@11 which was called
# once (7µs+27µs) by Class::MOP::BEGIN@19 at line 11 # spent 34µs making 1 call to Class::MOP::Attribute::BEGIN@11
# spent 27µs making 1 call to Exporter::import |
12 | |||||
13 | 1 | 800ns | our $VERSION = '0.98'; | ||
14 | 1 | 14µs | $VERSION = eval $VERSION; | ||
15 | 1 | 400ns | our $AUTHORITY = 'cpan:STEVAN'; | ||
16 | |||||
17 | 3 | 1.50ms | 2 | 144µs | # spent 76µs (8+68) within Class::MOP::Attribute::BEGIN@17 which was called
# once (8µs+68µs) by Class::MOP::BEGIN@19 at line 17 # spent 76µs making 1 call to Class::MOP::Attribute::BEGIN@17
# spent 68µ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 9.74ms (3.01+6.74) within Class::MOP::Attribute::new which was called 202 times, avg 48µs/call:
# 88 times (1.64ms+5.71ms) by Moose::Meta::Attribute::new at line 70 of Moose/Meta/Attribute.pm, avg 84µs/call
# 66 times (825µs+635µs) by Class::MOP::Mixin::HasAttributes::add_attribute at line 21 of Class/MOP/Mixin/HasAttributes.pm, avg 22µs/call
# once (22µs+24µs) by Moose::Exporter::BEGIN@11 at line 177 of Class/MOP.pm
# once (21µs+12µs) by Moose::Exporter::BEGIN@11 at line 261 of Class/MOP.pm
# once (17µs+10µs) by Moose::Exporter::BEGIN@11 at line 653 of Class/MOP.pm
# once (14µs+11µs) by Moose::Exporter::BEGIN@11 at line 610 of Class/MOP.pm
# once (14µs+10µs) by Moose::Exporter::BEGIN@11 at line 287 of Class/MOP.pm
# once (10µs+13µs) by Moose::Exporter::BEGIN@11 at line 222 of Class/MOP.pm
# once (13µs+10µs) by Moose::Exporter::BEGIN@11 at line 306 of Class/MOP.pm
# once (14µs+9µs) by Moose::Exporter::BEGIN@11 at line 219 of Class/MOP.pm
# once (9µs+13µs) by Moose::Exporter::BEGIN@11 at line 641 of Class/MOP.pm
# once (13µs+9µs) by Moose::Exporter::BEGIN@11 at line 322 of Class/MOP.pm
# once (13µs+9µs) by Moose::Exporter::BEGIN@11 at line 607 of Class/MOP.pm
# once (10µs+11µs) by Moose::Exporter::BEGIN@11 at line 558 of Class/MOP.pm
# once (15µs+7µs) by Moose::Exporter::BEGIN@11 at line 237 of Class/MOP.pm
# once (12µs+9µs) by Moose::Exporter::BEGIN@11 at line 495 of Class/MOP.pm
# once (12µs+8µs) by Moose::Exporter::BEGIN@11 at line 180 of Class/MOP.pm
# once (9µs+10µs) by Moose::Exporter::BEGIN@11 at line 505 of Class/MOP.pm
# once (10µs+10µs) by Moose::Exporter::BEGIN@11 at line 584 of Class/MOP.pm
# once (11µs+7µs) by Moose::Exporter::BEGIN@11 at line 192 of Class/MOP.pm
# once (11µs+7µs) by Moose::Exporter::BEGIN@11 at line 405 of Class/MOP.pm
# once (11µs+7µs) by Moose::BEGIN@18 at line 37 of Moose/Meta/Class.pm
# once (11µs+7µs) by Moose::Exporter::BEGIN@11 at line 425 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 565 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 325 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 358 of Class/MOP.pm
# once (11µs+7µs) by Moose::Exporter::BEGIN@11 at line 467 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 511 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 340 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 453 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 349 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 460 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 446 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 398 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 439 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 412 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 477 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 432 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 647 of Class/MOP.pm
# once (9µs+7µs) by Moose::Exporter::BEGIN@11 at line 529 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 575 of Class/MOP.pm
# once (9µs+7µs) by Moose::Exporter::BEGIN@11 at line 419 of Class/MOP.pm
# once (9µs+7µs) by Moose::Exporter::BEGIN@11 at line 523 of Class/MOP.pm
# once (9µs+7µs) by Moose::Exporter::BEGIN@11 at line 368 of Class/MOP.pm
# once (10µs+7µs) by Moose::Exporter::BEGIN@11 at line 626 of Class/MOP.pm
# once (9µs+7µs) by Moose::Exporter::BEGIN@11 at line 592 of Class/MOP.pm
# once (9µs+7µs) by Moose::Exporter::BEGIN@11 at line 517 of Class/MOP.pm
# once (9µs+7µs) by Moose::Exporter::BEGIN@11 at line 384 of Class/MOP.pm
# once (9µs+7µs) by Moose::Exporter::BEGIN@11 at line 632 of Class/MOP.pm
# once (9µs+7µs) by Moose::Exporter::BEGIN@11 at line 551 of Class/MOP.pm | ||||
29 | 202 | 384µs | my ( $class, @args ) = @_; | ||
30 | |||||
31 | 202 | 274µs | unshift @args, "name" if @args % 2 == 1; | ||
32 | 202 | 408µs | my %options = @args; | ||
33 | |||||
34 | 202 | 74µs | my $name = $options{name}; | ||
35 | |||||
36 | 202 | 33µs | (defined $name) | ||
37 | || confess "You must provide a name for the attribute"; | ||||
38 | |||||
39 | 202 | 185µs | $options{init_arg} = $name | ||
40 | if not exists $options{init_arg}; | ||||
41 | 202 | 107µs | if(exists $options{builder}){ | ||
42 | 1 | 1µs | confess("builder must be a defined scalar value which is a method name") | ||
43 | if ref $options{builder} || !(defined $options{builder}); | ||||
44 | 1 | 400ns | confess("Setting both default and builder is not allowed.") | ||
45 | if exists $options{default}; | ||||
46 | } else { | ||||
47 | 201 | 263µs | 68 | 215µs | ($class->is_default_a_coderef(\%options)) # spent 215µs making 68 calls to Class::MOP::Mixin::AttributeCore::is_default_a_coderef, avg 3µ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 | 202 | 62µs | 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 | 202 | 874µs | 202 | 6.52ms | $class->_new(\%options); # spent 4.93ms making 87 calls to Moose::Meta::Attribute::_new, avg 57µs/call
# spent 1.60ms making 115 calls to Class::MOP::Attribute::_new, avg 14µs/call |
57 | } | ||||
58 | |||||
59 | # spent 1.60ms (960µs+636µs) within Class::MOP::Attribute::_new which was called 115 times, avg 14µs/call:
# 115 times (960µs+636µs) by Class::MOP::Attribute::new at line 56, avg 14µs/call | ||||
60 | 115 | 28µs | my $class = shift; | ||
61 | |||||
62 | 115 | 31µs | 2 | 636µs | return Class::MOP::Class->initialize($class)->new_object(@_) # spent 630µs making 1 call to Class::MOP::Class::new_object
# spent 6µs making 1 call to Class::MOP::Class::initialize |
63 | if $class ne __PACKAGE__; | ||||
64 | |||||
65 | 114 | 39µs | my $options = @_ == 1 ? $_[0] : {@_}; | ||
66 | |||||
67 | 114 | 966µs | 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. | ||||
97 | sub 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 14.8ms (3.95+10.9) within Class::MOP::Attribute::initialize_instance_slot which was called 784 times, avg 19µs/call:
# 784 times (3.95ms+10.9ms) by Class::MOP::Class::_construct_instance at line 364 of Class/MOP/Class.pm, avg 19µs/call | ||||
106 | 784 | 286µs | my ($self, $meta_instance, $instance, $params) = @_; | ||
107 | 784 | 476µs | 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 | 784 | 2.44ms | 1110 | 10.9ms | if(defined $init_arg and exists $params->{$init_arg}){ # spent 7.33ms making 664 calls to Class::MOP::Attribute::_set_initial_slot_value, avg 11µs/call
# spent 3.53ms making 446 calls to Class::MOP::Mixin::AttributeCore::default, avg 8µ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 7.33ms (4.62+2.72) within Class::MOP::Attribute::_set_initial_slot_value which was called 664 times, avg 11µs/call:
# 664 times (4.62ms+2.72ms) by Class::MOP::Attribute::initialize_instance_slot at line 113, avg 11µs/call | ||||
142 | 664 | 325µs | my ($self, $meta_instance, $instance, $value) = @_; | ||
143 | |||||
144 | 664 | 1.55ms | 664 | 352µs | my $slot_name = $self->name; # spent 352µs making 664 calls to Class::MOP::Mixin::AttributeCore::name, avg 530ns/call |
145 | |||||
146 | 664 | 2.15ms | 1328 | 2.37ms | return $meta_instance->set_slot_value($instance, $slot_name, $value) # spent 1.49ms making 664 calls to Class::MOP::Instance::set_slot_value, avg 2µs/call
# spent 871µs making 664 calls to Class::MOP::Mixin::AttributeCore::has_initializer, avg 1µ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 | |||||
159 | 1126 | 2.21ms | # spent 1.16ms within Class::MOP::Attribute::associated_class which was called 1126 times, avg 1µs/call:
# 276 times (272µs+0s) by Class::MOP::Attribute::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Class/MOP/Attribute.pm:340] at line 332, avg 984ns/call
# 270 times (308µs+0s) by Class::MOP::Attribute::install_accessors at line 352, avg 1µs/call
# 110 times (98µs+0s) by Moose::Meta::Attribute::_process_accessors at line 569 of Moose/Meta/Attribute.pm, avg 886ns/call
# 89 times (81µs+0s) by Moose::Meta::Method::Accessor::_inline_get at line 252 of Moose/Meta/Method/Accessor.pm, avg 910ns/call
# 84 times (69µs+0s) by Class::MOP::Attribute::_process_accessors at line 320, avg 821ns/call
# 62 times (93µs+0s) by Class::MOP::Attribute::get_read_method_ref at line 184, avg 2µs/call
# 57 times (49µs+0s) by Class::MOP::Attribute::_process_accessors at line 310, avg 860ns/call
# 52 times (48µs+0s) by Class::MOP::Method::Accessor::_generate_reader_method_inline at line 155 of Class/MOP/Method/Accessor.pm, avg 921ns/call
# 42 times (50µs+0s) by Moose::Meta::Method::Accessor::_inline_store at line 218 of Moose/Meta/Method/Accessor.pm, avg 1µs/call
# 31 times (29µs+0s) by Class::MOP::Method::Accessor::_generate_predicate_method_inline at line 190 of Class/MOP/Method/Accessor.pm, avg 932ns/call
# 22 times (26µs+0s) by Moose::Meta::Method::Accessor::_inline_has at line 270 of Moose/Meta/Method/Accessor.pm, avg 1µs/call
# 15 times (14µs+0s) by Class::MOP::Method::Accessor::_generate_accessor_method_inline at line 136 of Class/MOP/Method/Accessor.pm, avg 907ns/call
# 3 times (3µs+0s) by Class::MOP::Method::Accessor::_generate_clearer_method_inline at line 207 of Class/MOP/Method/Accessor.pm, avg 1µs/call
# 3 times (2µs+0s) by Class::MOP::Method::Accessor::_generate_writer_method_inline at line 173 of Class/MOP/Method/Accessor.pm, avg 833ns/call
# 2 times (2µs+0s) by Class::MOP::Attribute::get_write_method_ref at line 209, avg 1µs/call
# 2 times (2µs+0s) by Class::MOP::Class:::after at line 121 of MooseX/AttributeHelpers/Trait/Base.pm, avg 1µs/call
# once (4µs+0s) by Class::MOP::Class:::around at line 78 of MooseX/ClassAttribute/Role/Meta/Attribute.pm
# once (2µs+0s) by Class::MOP::Class:::around at line 111 of MooseX/ClassAttribute/Role/Meta/Attribute.pm
# once (1µs+0s) by MooseX::ClassAttribute::Meta::Method::Accessor::_inline_store at line 48 of MooseX/ClassAttribute/Meta/Method/Accessor.pm
# once (1µs+0s) by Moose::Meta::Method::Accessor::_inline_get_old_value_for_trigger at line 232 of Moose/Meta/Method/Accessor.pm
# once (1µs+0s) by MooseX::ClassAttribute::Meta::Method::Accessor::_inline_get at line 62 of MooseX/ClassAttribute/Meta/Method/Accessor.pm
# once (900ns+0s) by MooseX::ClassAttribute::Meta::Method::Accessor::_inline_check_lazy at line 99 of MooseX/ClassAttribute/Meta/Method/Accessor.pm | ||
160 | 86 | 214µs | # spent 106µs within Class::MOP::Attribute::associated_methods which was called 86 times, avg 1µs/call:
# 86 times (106µs+0s) by Moose::Meta::Attribute::_check_associated_methods at line 551 of Moose/Meta/Attribute.pm, avg 1µs/call | ||
161 | |||||
162 | # spent 425µs (302+123) within Class::MOP::Attribute::get_read_method which was called 31 times, avg 14µs/call:
# 31 times (302µs+123µs) by Class::MOP::Attribute::get_read_method_ref at line 184, avg 14µs/call | ||||
163 | 31 | 12µs | my $self = shift; | ||
164 | 31 | 147µs | 60 | 123µs | my $reader = $self->reader || $self->accessor; # spent 63µs making 31 calls to Class::MOP::Mixin::AttributeCore::reader, avg 2µs/call
# spent 60µs making 29 calls to Class::MOP::Mixin::AttributeCore::accessor, avg 2µs/call |
165 | # normal case ... | ||||
166 | 31 | 97µs | return $reader unless ref $reader; | ||
167 | # the HASH ref case | ||||
168 | my ($name) = %$reader; | ||||
169 | return $name; | ||||
170 | } | ||||
171 | |||||
172 | # spent 32µs (24+8) within Class::MOP::Attribute::get_write_method which was called 2 times, avg 16µs/call:
# 2 times (24µs+8µs) by Class::MOP::Attribute::get_write_method_ref at line 204, avg 16µs/call | ||||
173 | 2 | 500ns | my $self = shift; | ||
174 | 2 | 14µs | 4 | 8µs | my $writer = $self->writer || $self->accessor; # spent 4µs making 2 calls to Class::MOP::Mixin::AttributeCore::writer, avg 2µs/call
# spent 4µs making 2 calls to Class::MOP::Mixin::AttributeCore::accessor, avg 2µs/call |
175 | # normal case ... | ||||
176 | 2 | 6µs | return $writer unless ref $writer; | ||
177 | # the HASH ref case | ||||
178 | my ($name) = %$writer; | ||||
179 | return $name; | ||||
180 | } | ||||
181 | |||||
182 | # spent 2.41ms (463µs+1.95) within Class::MOP::Attribute::get_read_method_ref which was called 31 times, avg 78µs/call:
# 29 times (435µs+1.88ms) by Moose::Meta::Class::new_object at line 267 of Moose/Meta/Class.pm, avg 80µs/call
# 2 times (28µs+71µs) by Class::MOP::Class:::after at line 126 of MooseX/AttributeHelpers/Trait/Base.pm, avg 49µs/call | ||||
183 | 31 | 14µs | my $self = shift; | ||
184 | 31 | 341µs | 124 | 1.95ms | if ((my $reader = $self->get_read_method) && $self->associated_class) { # spent 1.43ms making 31 calls to Class::MOP::Mixin::HasMethods::get_method, avg 46µs/call
# spent 425µs making 31 calls to Class::MOP::Attribute::get_read_method, avg 14µs/call
# spent 93µs making 62 calls to Class::MOP::Attribute::associated_class, avg 2µ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 | |||||
202 | # spent 137µs (44+93) within Class::MOP::Attribute::get_write_method_ref which was called 2 times, avg 68µs/call:
# 2 times (44µs+93µs) by Class::MOP::Class:::after at line 127 of MooseX/AttributeHelpers/Trait/Base.pm, avg 68µs/call | ||||
203 | 2 | 1µs | my $self = shift; | ||
204 | 2 | 7µs | 2 | 32µs | if ((my $writer = $self->get_write_method) && $self->associated_class) { # spent 32µs making 2 calls to Class::MOP::Attribute::get_write_method, avg 16µs/call |
205 | return $self->associated_class->get_method($writer); | ||||
206 | } | ||||
207 | else { | ||||
208 | 2 | 6µs | my $code = sub { $self->set_value(@_) }; | ||
209 | 2 | 22µs | 8 | 61µs | if (my $class = $self->associated_class) { # spent 53µs making 2 calls to Class::MOP::Method::wrap, avg 27µs/call
# spent 4µs making 2 calls to Class::MOP::Mixin::HasMethods::method_metaclass, avg 2µs/call
# spent 2µs making 2 calls to Class::MOP::Attribute::associated_class, avg 1µs/call
# spent 1µs making 2 calls to Class::MOP::Package::name, avg 600ns/call |
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 | |||||
224 | 1810 | 5.76ms | 1810 | 726µs | # spent 4.84ms (4.12+726µs) within Class::MOP::Attribute::slots which was called 1810 times, avg 3µs/call:
# 1655 times (3.70ms+646µs) by Class::MOP::Instance::BUILDARGS at line 28 of Class/MOP/Instance.pm, avg 3µs/call
# 89 times (239µs+45µs) by Moose::Meta::Method::Accessor::_inline_get at line 254 of Moose/Meta/Method/Accessor.pm, avg 3µs/call
# 42 times (111µs+22µs) by Moose::Meta::Method::Accessor::_inline_store at line 220 of Moose/Meta/Method/Accessor.pm, avg 3µs/call
# 22 times (56µs+11µs) by Moose::Meta::Method::Accessor::_inline_has at line 272 of Moose/Meta/Method/Accessor.pm, avg 3µs/call
# once (3µs+800ns) by MooseX::ClassAttribute::Meta::Method::Accessor::_inline_store at line 50 of MooseX/ClassAttribute/Meta/Method/Accessor.pm
# once (3µs+800ns) by MooseX::ClassAttribute::Meta::Method::Accessor::_inline_get at line 64 of MooseX/ClassAttribute/Meta/Method/Accessor.pm # spent 726µs making 1810 calls to Class::MOP::Mixin::AttributeCore::name, avg 401ns/call |
225 | |||||
226 | # class association | ||||
227 | |||||
228 | # spent 1.87ms (1.43+439µs) within Class::MOP::Attribute::attach_to_class which was called 202 times, avg 9µs/call:
# 201 times (1.34ms+431µs) by Class::MOP::Class::_attach_attribute at line 503 of Class/MOP/Class.pm, avg 9µs/call
# once (86µs+8µs) by Class::MOP::Class:::around at line 39 of MooseX/ClassAttribute/Role/Meta/Attribute.pm | ||||
229 | 202 | 118µs | my ($self, $class) = @_; | ||
230 | 202 | 919µs | 404 | 240µs | (blessed($class) && $class->isa('Class::MOP::Class')) # spent 126µs making 202 calls to UNIVERSAL::isa, avg 626ns/call
# spent 113µs making 202 calls to Scalar::Util::blessed, avg 562ns/call |
231 | || confess "You must pass a Class::MOP::Class instance (or a subclass)"; | ||||
232 | 202 | 915µs | 202 | 199µs | weaken($self->{'associated_class'} = $class); # spent 199µs making 202 calls to Scalar::Util::weaken, avg 984ns/call |
233 | } | ||||
234 | |||||
235 | sub detach_from_class { | ||||
236 | my $self = shift; | ||||
237 | $self->{'associated_class'} = undef; | ||||
238 | } | ||||
239 | |||||
240 | # method association | ||||
241 | |||||
242 | # spent 873µs within Class::MOP::Attribute::associate_method which was called 342 times, avg 3µs/call:
# 276 times (738µs+0s) by Class::MOP::Attribute::_process_accessors at line 344, avg 3µs/call
# 57 times (115µs+0s) by Class::MOP::Attribute::_process_accessors at line 316, avg 2µs/call
# 9 times (19µs+0s) by Class::MOP::Class:::after at line 191 of MooseX/AttributeHelpers/Trait/Base.pm, avg 2µs/call | ||||
243 | 342 | 178µs | my ($self, $method) = @_; | ||
244 | 342 | 827µs | push @{$self->{'associated_methods'}} => $method; | ||
245 | } | ||||
246 | |||||
247 | ## Slot management | ||||
248 | |||||
249 | # spent 10.4ms (2.99+7.42) within Class::MOP::Attribute::set_initial_value which was called 335 times, avg 31µs/call:
# 335 times (2.99ms+7.42ms) by Moose::Meta::Attribute::initialize_instance_slot at line 400 of Moose/Meta/Attribute.pm, avg 31µs/call | ||||
250 | 335 | 197µs | my ($self, $instance, $value) = @_; | ||
251 | 335 | 1.92ms | 1005 | 7.41ms | $self->_set_initial_slot_value( # spent 4.71ms making 335 calls to Moose::Meta::Attribute::_set_initial_slot_value, avg 14µs/call
# spent 2.09ms making 335 calls to Class::MOP::Class::initialize, avg 6µs/call, recursion: max depth 1, time 13µs
# spent 539µs making 324 calls to Class::MOP::Class::get_meta_instance, avg 2µs/call
# spent 92µs making 11 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance, avg 8µs/call |
252 | Class::MOP::Class->initialize(ref($instance))->get_meta_instance, | ||||
253 | $instance, | ||||
254 | $value | ||||
255 | ); | ||||
256 | } | ||||
257 | |||||
258 | 290 | 618µs | 290 | 6.60ms | # spent 7.31ms (712µs+6.60) within Class::MOP::Attribute::set_value which was called 290 times, avg 25µs/call:
# 290 times (712µs+6.60ms) by Class::MOP::Class::_clone_instance at line 422 of Class/MOP/Class.pm, avg 25µs/call # spent 6.60ms making 290 calls to Class::MOP::Attribute::set_raw_value, avg 23µs/call |
259 | 6 | 20µs | 6 | 142µs | # spent 161µs (19+142) within Class::MOP::Attribute::get_value which was called 6 times, avg 27µs/call:
# 6 times (19µs+142µ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 27µs/call # spent 142µs making 6 calls to Class::MOP::Attribute::get_raw_value, avg 24µs/call |
260 | |||||
261 | # spent 6.60ms (2.47+4.13) within Class::MOP::Attribute::set_raw_value which was called 290 times, avg 23µs/call:
# 290 times (2.47ms+4.13ms) by Class::MOP::Attribute::set_value at line 258, avg 23µs/call | ||||
262 | 290 | 190µs | my ($self, $instance, $value) = @_; | ||
263 | |||||
264 | 290 | 1.83ms | 1160 | 4.13ms | Class::MOP::Class->initialize(ref($instance)) # spent 1.89ms making 284 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance, avg 7µs/call
# spent 1.37ms making 290 calls to Class::MOP::Class::initialize, avg 5µs/call
# spent 675µs making 290 calls to Class::MOP::Instance::set_slot_value, avg 2µs/call
# spent 182µs making 290 calls to Class::MOP::Mixin::AttributeCore::name, avg 628ns/call
# spent 8µs making 6 calls to Class::MOP::Class::get_meta_instance, avg 1µs/call |
265 | ->get_meta_instance | ||||
266 | ->set_slot_value($instance, $self->name, $value); | ||||
267 | } | ||||
268 | |||||
269 | # spent 142µs (62+80) within Class::MOP::Attribute::get_raw_value which was called 6 times, avg 24µs/call:
# 6 times (62µs+80µs) by Class::MOP::Attribute::get_value at line 259, avg 24µs/call | ||||
270 | 6 | 3µs | my ($self, $instance) = @_; | ||
271 | |||||
272 | 6 | 44µs | 24 | 80µs | Class::MOP::Class->initialize(ref($instance)) # spent 32µs making 3 calls to Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance, avg 11µs/call
# spent 28µs making 6 calls to Class::MOP::Class::initialize, avg 5µs/call
# spent 12µs making 6 calls to Class::MOP::Instance::get_slot_value, avg 2µs/call
# spent 4µs making 3 calls to Class::MOP::Class::get_meta_instance, avg 1µs/call
# spent 3µs making 6 calls to Class::MOP::Mixin::AttributeCore::name, avg 567ns/call |
273 | ->get_meta_instance | ||||
274 | ->get_slot_value($instance, $self->name); | ||||
275 | } | ||||
276 | |||||
277 | # spent 57µs (28+30) within Class::MOP::Attribute::has_value which was called 2 times, avg 29µs/call:
# 2 times (28µs+30µs) by Moose::Meta::Mixin::AttributeCore::has_handles at line 119 of Class/MOP/Method/Accessor.pm, avg 29µs/call | ||||
278 | 2 | 2µs | my ($self, $instance) = @_; | ||
279 | |||||
280 | 2 | 21µs | 8 | 30µs | Class::MOP::Class->initialize(ref($instance)) # spent 11µs making 2 calls to Class::MOP::Class::initialize, avg 6µs/call
# spent 8µs making 2 calls to Class::MOP::Instance::is_slot_initialized, avg 4µs/call
# spent 8µs making 1 call to Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance
# spent 2µs making 1 call to Class::MOP::Class::get_meta_instance
# spent 1µs making 2 calls to Class::MOP::Mixin::AttributeCore::name, avg 650ns/call |
281 | ->get_meta_instance | ||||
282 | ->is_slot_initialized($instance, $self->name); | ||||
283 | } | ||||
284 | |||||
285 | sub 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 | |||||
295 | 223 | 451µs | # spent 196µs within Class::MOP::Attribute::accessor_metaclass which was called 223 times, avg 879ns/call:
# 166 times (146µs+0s) by Class::MOP::Attribute::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Class/MOP/Attribute.pm:340] at line 332, avg 877ns/call
# 57 times (50µs+0s) by Class::MOP::Attribute::_process_accessors at line 310, avg 884ns/call | ||
296 | |||||
297 | # spent 94.8ms (7.48+87.4) within Class::MOP::Attribute::_process_accessors which was called 333 times, avg 285µs/call:
# 148 times (3.10ms+19.2ms) by Class::MOP::Attribute::install_accessors at line 358, avg 151µs/call
# 110 times (2.83ms+60.8ms) by Moose::Meta::Attribute::_process_accessors at line 578 of Moose/Meta/Attribute.pm, avg 578µs/call
# 36 times (687µs+3.02ms) by Class::MOP::Attribute::install_accessors at line 366, avg 103µs/call
# 31 times (708µs+3.61ms) by Class::MOP::Attribute::install_accessors at line 354, avg 139µs/call
# 8 times (153µs+721µs) by Class::MOP::Attribute::install_accessors at line 362, avg 109µs/call | ||||
298 | 333 | 184µs | my ($self, $type, $accessor, $generate_as_inline_methods) = @_; | ||
299 | |||||
300 | 333 | 36µs | my $method_ctx; | ||
301 | |||||
302 | 333 | 625µs | 333 | 338µs | if ( my $ctx = $self->definition_context ) { # spent 338µs making 333 calls to Class::MOP::Mixin::AttributeCore::definition_context, avg 1µs/call |
303 | $method_ctx = { %$ctx }; | ||||
304 | } | ||||
305 | |||||
306 | 333 | 78µs | if (ref($accessor)) { | ||
307 | 57 | 12µs | (ref($accessor) eq 'HASH') | ||
308 | || confess "bad accessor/reader/writer/predicate/clearer format, must be a HASH ref"; | ||||
309 | 57 | 102µs | my ($name, $method) = %{$accessor}; | ||
310 | 57 | 312µs | 228 | 1.76ms | $method = $self->accessor_metaclass->wrap( # spent 1.62ms making 57 calls to Class::MOP::Method::wrap, avg 28µs/call
# spent 50µs making 57 calls to Class::MOP::Attribute::accessor_metaclass, avg 884ns/call
# spent 49µs making 57 calls to Class::MOP::Attribute::associated_class, avg 860ns/call
# spent 41µs making 57 calls to Class::MOP::Package::name, avg 714ns/call |
311 | $method, | ||||
312 | package_name => $self->associated_class->name, | ||||
313 | name => $name, | ||||
314 | definition_context => $method_ctx, | ||||
315 | ); | ||||
316 | 57 | 68µs | 57 | 115µs | $self->associate_method($method); # spent 115µs making 57 calls to Class::MOP::Attribute::associate_method, avg 2µs/call |
317 | 57 | 131µs | return ($name, $method); | ||
318 | } | ||||
319 | else { | ||||
320 | 276 | 271µs | 252 | 215µs | my $inline_me = ($generate_as_inline_methods && $self->associated_class->instance_metaclass->is_inlinable); # spent 83µs making 84 calls to Class::MOP::Class::instance_metaclass, avg 987ns/call
# spent 69µs making 84 calls to Class::MOP::Attribute::associated_class, avg 821ns/call
# spent 63µs making 84 calls to Class::MOP::Instance::is_inlinable, avg 755ns/call |
321 | 276 | 34µs | my $method; | ||
322 | # spent 80.3ms (3.34+77.0) within Class::MOP::Attribute::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Class/MOP/Attribute.pm:340] which was called 276 times, avg 291µs/call:
# 276 times (3.34ms+77.0ms) by Try::Tiny::try at line 76 of Try/Tiny.pm, avg 291µs/call | ||||
323 | 276 | 42µs | if ( $method_ctx ) { | ||
324 | 88 | 86µs | my $desc = "accessor $accessor"; | ||
325 | 88 | 339µs | 106 | 62µs | if ( $accessor ne $self->name ) { # spent 62µs making 106 calls to Class::MOP::Mixin::AttributeCore::name, avg 587ns/call |
326 | $desc .= " of attribute " . $self->name; | ||||
327 | } | ||||
328 | |||||
329 | 88 | 80µs | $method_ctx->{description} = $desc; | ||
330 | } | ||||
331 | |||||
332 | 276 | 2.18ms | 1104 | 76.9ms | $method = $self->accessor_metaclass->new( # spent 76.2ms making 276 calls to Class::MOP::Method::Accessor::new, avg 276µs/call
# spent 272µs making 276 calls to Class::MOP::Attribute::associated_class, avg 984ns/call
# spent 185µs making 276 calls to Class::MOP::Package::name, avg 670ns/call
# spent 146µs making 166 calls to Class::MOP::Attribute::accessor_metaclass, avg 877ns/call
# spent 120µs making 109 calls to Moose::Meta::Attribute::accessor_metaclass, avg 1µs/call
# spent 10µs making 1 call to Class::MOP::Class::__ANON__::SERIAL::2::accessor_metaclass |
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 | 276 | 2.99ms | 552 | 19.3ms | }; # spent 83.5ms making 276 calls to Try::Tiny::try, avg 302µs/call, recursion: max depth 2, time 64.9ms
# spent 733µs making 276 calls to Try::Tiny::catch, avg 3µs/call |
344 | 276 | 504µs | 276 | 738µs | $self->associate_method($method); # spent 738µs making 276 calls to Class::MOP::Attribute::associate_method, avg 3µs/call |
345 | 276 | 688µs | return ($accessor, $method); | ||
346 | } | ||||
347 | } | ||||
348 | |||||
349 | # spent 124ms (6.63+118) within Class::MOP::Attribute::install_accessors which was called 270 times, avg 460µs/call:
# 114 times (2.58ms+17.4ms) by Class::MOP::Class::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Class/MOP/Class.pm:515] at line 514 of Class/MOP/Class.pm, avg 176µs/call
# 89 times (2.56ms+75.1ms) by Moose::Meta::Attribute::install_accessors at line 544 of Moose/Meta/Attribute.pm, avg 873µs/call
# 67 times (1.48ms+25.1ms) by Class::MOP::Class::_inline_accessors at line 1030 of Class/MOP/Class.pm, avg 396µs/call | ||||
350 | 270 | 54µs | my $self = shift; | ||
351 | 270 | 45µs | my $inline = shift; | ||
352 | 270 | 294µs | 270 | 308µs | my $class = $self->associated_class; # spent 308µs making 270 calls to Class::MOP::Attribute::associated_class, avg 1µs/call |
353 | |||||
354 | 270 | 601µs | 426 | 23.8ms | $class->add_method( # spent 16.5ms making 21 calls to Moose::Meta::Attribute::_process_accessors, avg 784µs/call
# spent 4.32ms making 31 calls to Class::MOP::Attribute::_process_accessors, avg 139µs/call
# spent 2.50ms making 52 calls to Class::MOP::Mixin::HasMethods::add_method, avg 48µs/call
# spent 395µs making 270 calls to Class::MOP::Mixin::AttributeCore::has_accessor, avg 1µs/call
# spent 71µs making 52 calls to Class::MOP::Mixin::AttributeCore::accessor, avg 1µs/call |
355 | $self->_process_accessors('accessor' => $self->accessor(), $inline) | ||||
356 | ) if $self->has_accessor(); | ||||
357 | |||||
358 | 270 | 1.35ms | 918 | 80.2ms | $class->add_method( # spent 47.3ms making 68 calls to Moose::Meta::Attribute::_process_accessors, avg 696µs/call
# spent 22.3ms making 148 calls to Class::MOP::Attribute::_process_accessors, avg 151µs/call
# spent 9.91ms making 216 calls to Class::MOP::Mixin::HasMethods::add_method, avg 46µs/call
# spent 356µs making 270 calls to Class::MOP::Mixin::AttributeCore::has_reader, avg 1µs/call
# spent 275µs making 216 calls to Class::MOP::Mixin::AttributeCore::reader, avg 1µs/call |
359 | $self->_process_accessors('reader' => $self->reader(), $inline) | ||||
360 | ) if $self->has_reader(); | ||||
361 | |||||
362 | 270 | 430µs | 294 | 1.63ms | $class->add_method( # spent 874µs making 8 calls to Class::MOP::Attribute::_process_accessors, avg 109µs/call
# spent 424µs making 270 calls to Class::MOP::Mixin::AttributeCore::has_writer, avg 2µs/call
# spent 325µs making 8 calls to Class::MOP::Mixin::HasMethods::add_method, avg 41µs/call
# spent 12µs making 8 calls to Class::MOP::Mixin::AttributeCore::writer, avg 1µs/call |
363 | $self->_process_accessors('writer' => $self->writer(), $inline) | ||||
364 | ) if $self->has_writer(); | ||||
365 | |||||
366 | 270 | 584µs | 432 | 10.5ms | $class->add_method( # spent 4.11ms making 18 calls to Moose::Meta::Attribute::_process_accessors, avg 228µs/call
# spent 3.71ms making 36 calls to Class::MOP::Attribute::_process_accessors, avg 103µs/call
# spent 2.28ms making 54 calls to Class::MOP::Mixin::HasMethods::add_method, avg 42µs/call
# spent 335µs making 270 calls to Class::MOP::Mixin::AttributeCore::has_predicate, avg 1µs/call
# spent 80µs making 54 calls to Class::MOP::Mixin::AttributeCore::predicate, avg 1µs/call |
367 | $self->_process_accessors('predicate' => $self->predicate(), $inline) | ||||
368 | ) if $self->has_predicate(); | ||||
369 | |||||
370 | 270 | 340µs | 279 | 1.23ms | $class->add_method( # spent 740µs making 3 calls to Moose::Meta::Attribute::_process_accessors, avg 247µs/call
# spent 321µs making 270 calls to Class::MOP::Mixin::AttributeCore::has_clearer, avg 1µs/call
# spent 161µs making 3 calls to Class::MOP::Mixin::HasMethods::add_method, avg 54µs/call
# spent 6µs making 3 calls to Class::MOP::Mixin::AttributeCore::clearer, avg 2µs/call |
371 | $self->_process_accessors('clearer' => $self->clearer(), $inline) | ||||
372 | ) if $self->has_clearer(); | ||||
373 | |||||
374 | 270 | 548µs | return; | ||
375 | } | ||||
376 | |||||
377 | { | ||||
378 | 1 | 200ns | my $_remove_accessor = sub { | ||
379 | my ($accessor, $class) = @_; | ||||
380 | if (ref($accessor) && ref($accessor) eq 'HASH') { | ||||
381 | ($accessor) = keys %{$accessor}; | ||||
382 | } | ||||
383 | my $method = $class->get_method($accessor); | ||||
384 | $class->remove_method($accessor) | ||||
385 | if (ref($method) && $method->isa('Class::MOP::Method::Accessor')); | ||||
386 | 1 | 3µs | }; | ||
387 | |||||
388 | sub remove_accessors { | ||||
389 | 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(); | ||||
396 | $_remove_accessor->($self->reader(), $self->associated_class()) if $self->has_reader(); | ||||
397 | $_remove_accessor->($self->writer(), $self->associated_class()) if $self->has_writer(); | ||||
398 | $_remove_accessor->($self->predicate(), $self->associated_class()) if $self->has_predicate(); | ||||
399 | $_remove_accessor->($self->clearer(), $self->associated_class()) if $self->has_clearer(); | ||||
400 | return; | ||||
401 | } | ||||
402 | |||||
403 | } | ||||
404 | |||||
405 | 1 | 10µs | 1; | ||
406 | |||||
407 | __END__ | ||||
408 | |||||
409 | =pod | ||||
410 | |||||
411 | =head1 NAME | ||||
412 | |||||
413 | Class::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 | |||||
438 | The Attribute Protocol is almost entirely an invention of | ||||
439 | C<Class::MOP>. Perl 5 does not have a consistent notion of | ||||
440 | attributes. There are so many ways in which this is done, and very few | ||||
441 | (if any) are easily discoverable by this module. | ||||
442 | |||||
443 | With that said, this module attempts to inject some order into this | ||||
444 | chaos, by introducing a consistent API which can be used to create | ||||
445 | object attributes. | ||||
446 | |||||
447 | =head1 METHODS | ||||
448 | |||||
449 | =head2 Creation | ||||
450 | |||||
451 | =over 4 | ||||
452 | |||||
453 | =item B<< Class::MOP::Attribute->new($name, ?%options) >> | ||||
454 | |||||
455 | An attribute must (at the very least), have a C<$name>. All other | ||||
456 | C<%options> are added as key-value pairs. | ||||
457 | |||||
458 | =over 8 | ||||
459 | |||||
460 | =item * init_arg | ||||
461 | |||||
462 | This is a string value representing the expected key in an | ||||
463 | initialization hash. For instance, if we have an C<init_arg> value of | ||||
464 | C<-foo>, then the following code will Just Work. | ||||
465 | |||||
466 | MyClass->meta->new_object( -foo => 'Hello There' ); | ||||
467 | |||||
468 | If an init_arg is not assigned, it will automatically use the | ||||
469 | attribute's name. If C<init_arg> is explicitly set to C<undef>, the | ||||
470 | attribute cannot be specified during initialization. | ||||
471 | |||||
472 | =item * builder | ||||
473 | |||||
474 | This provides the name of a method that will be called to initialize | ||||
475 | the attribute. This method will be called on the object after it is | ||||
476 | constructed. It is expected to return a valid value for the attribute. | ||||
477 | |||||
478 | =item * default | ||||
479 | |||||
480 | This can be used to provide an explicit default for initializing the | ||||
481 | attribute. If the default you provide is a subroutine reference, then | ||||
482 | this reference will be called I<as a method> on the object. | ||||
483 | |||||
484 | If the value is a simple scalar (string or number), then it can be | ||||
485 | just passed as is. However, if you wish to initialize it with a HASH | ||||
486 | or ARRAY ref, then you need to wrap that inside a subroutine | ||||
487 | reference: | ||||
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 | |||||
503 | If you wish to initialize an attribute with a subroutine reference | ||||
504 | itself, 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 | |||||
514 | And lastly, if the value of your attribute is dependent upon some | ||||
515 | other aspect of the instance structure, then you can take advantage of | ||||
516 | the 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 | |||||
524 | Note that there is no guarantee that attributes are initialized in any | ||||
525 | particular order, so you cannot rely on the value of some other | ||||
526 | attribute when generating the default. | ||||
527 | |||||
528 | =item * initializer | ||||
529 | |||||
530 | This option can be either a method name or a subroutine | ||||
531 | reference. This method will be called when setting the attribute's | ||||
532 | value in the constructor. Unlike C<default> and C<builder>, the | ||||
533 | initializer is only called when a value is provided to the | ||||
534 | constructor. The initializer allows you to munge this value during | ||||
535 | object construction. | ||||
536 | |||||
537 | The initializer is called as a method with three arguments. The first | ||||
538 | is the value that was passed to the constructor. The second is a | ||||
539 | subroutine reference that can be called to actually set the | ||||
540 | attribute's value, and the last is the associated | ||||
541 | C<Class::MOP::Attribute> object. | ||||
542 | |||||
543 | This contrived example shows an initializer that sets the attribute to | ||||
544 | twice 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 | |||||
555 | Since an initializer can be a method name, you can easily make | ||||
556 | attribute initialization use the writer: | ||||
557 | |||||
558 | Class::MOP::Attribute->new( | ||||
559 | 'some_attr' => ( | ||||
560 | writer => 'some_attr', | ||||
561 | initializer => 'some_attr', | ||||
562 | ) | ||||
563 | ); | ||||
564 | |||||
565 | Your writer will need to examine C<@_> and determine under which | ||||
566 | context it is being called. | ||||
567 | |||||
568 | =back | ||||
569 | |||||
570 | The C<accessor>, C<reader>, C<writer>, C<predicate> and C<clearer> | ||||
571 | options all accept the same parameters. You can provide the name of | ||||
572 | the method, in which case an appropriate default method will be | ||||
573 | generated for you. Or instead you can also provide hash reference | ||||
574 | containing exactly one key (the method name) and one value. The value | ||||
575 | should be a subroutine reference, which will be installed as the | ||||
576 | method itself. | ||||
577 | |||||
578 | =over 8 | ||||
579 | |||||
580 | =item * accessor | ||||
581 | |||||
582 | An C<accessor> is a standard Perl-style read/write accessor. It will | ||||
583 | return the value of the attribute, and if a value is passed as an | ||||
584 | argument, it will assign that value to the attribute. | ||||
585 | |||||
586 | Note that C<undef> is a legitimate value, so this will work: | ||||
587 | |||||
588 | $object->set_something(undef); | ||||
589 | |||||
590 | =item * reader | ||||
591 | |||||
592 | This is a basic read-only accessor. It returns the value of the | ||||
593 | attribute. | ||||
594 | |||||
595 | =item * writer | ||||
596 | |||||
597 | This is a basic write accessor, it accepts a single argument, and | ||||
598 | assigns that value to the attribute. | ||||
599 | |||||
600 | Note that C<undef> is a legitimate value, so this will work: | ||||
601 | |||||
602 | $object->set_something(undef); | ||||
603 | |||||
604 | =item * predicate | ||||
605 | |||||
606 | The predicate method returns a boolean indicating whether or not the | ||||
607 | attribute has been explicitly set. | ||||
608 | |||||
609 | Note that the predicate returns true even if the attribute was set to | ||||
610 | a false value (C<0> or C<undef>). | ||||
611 | |||||
612 | =item * clearer | ||||
613 | |||||
614 | This method will uninitialize the attribute. After an attribute is | ||||
615 | cleared, its C<predicate> will return false. | ||||
616 | |||||
617 | =item * definition_context | ||||
618 | |||||
619 | Mostly, this exists as a hook for the benefit of Moose. | ||||
620 | |||||
621 | This option should be a hash reference containing several keys which | ||||
622 | will be used when inlining the attribute's accessors. The keys should | ||||
623 | include C<line>, the line number where the attribute was created, and | ||||
624 | either C<file> or C<description>. | ||||
625 | |||||
626 | This information will ultimately be used when eval'ing inlined | ||||
627 | accessor code so that error messages report a useful line and file | ||||
628 | name. | ||||
629 | |||||
630 | =back | ||||
631 | |||||
632 | =item B<< $attr->clone(%options) >> | ||||
633 | |||||
634 | This clones the attribute. Any options you provide will override the | ||||
635 | settings of the original attribute. You can change the name of the new | ||||
636 | attribute by passing a C<name> key in C<%options>. | ||||
637 | |||||
638 | =back | ||||
639 | |||||
640 | =head2 Informational | ||||
641 | |||||
642 | These are all basic read-only accessors for the values passed into | ||||
643 | the constructor. | ||||
644 | |||||
645 | =over 4 | ||||
646 | |||||
647 | =item B<< $attr->name >> | ||||
648 | |||||
649 | Returns 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 | |||||
661 | The C<accessor>, C<reader>, C<writer>, C<predicate>, and C<clearer> | ||||
662 | methods all return exactly what was passed to the constructor, so it | ||||
663 | can be either a string containing a method name, or a hash reference. | ||||
664 | |||||
665 | =item B<< $attr->initializer >> | ||||
666 | |||||
667 | Returns the initializer as passed to the constructor, so this may be | ||||
668 | either 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 | |||||
676 | The C<$instance> argument is optional. If you don't pass it, the | ||||
677 | return value for this method is exactly what was passed to the | ||||
678 | constructor, either a simple scalar or a subroutine reference. | ||||
679 | |||||
680 | If you I<do> pass an C<$instance> and the default is a subroutine | ||||
681 | reference, then the reference is called as a method on the | ||||
682 | C<$instance> and the generated value is returned. | ||||
683 | |||||
684 | =item B<< $attr->slots >> | ||||
685 | |||||
686 | Return a list of slots required by the attribute. This is usually just | ||||
687 | one, the name of the attribute. | ||||
688 | |||||
689 | A slot is the name of the hash key used to store the attribute in an | ||||
690 | object instance. | ||||
691 | |||||
692 | =item B<< $attr->get_read_method >> | ||||
693 | |||||
694 | =item B<< $attr->get_write_method >> | ||||
695 | |||||
696 | Returns the name of a method suitable for reading or writing the value | ||||
697 | of the attribute in the associated class. | ||||
698 | |||||
699 | If an attribute is read- or write-only, then these methods can return | ||||
700 | C<undef> as appropriate. | ||||
701 | |||||
702 | =item B<< $attr->has_read_method >> | ||||
703 | |||||
704 | =item B<< $attr->has_write_method >> | ||||
705 | |||||
706 | This returns a boolean indicating whether the attribute has a I<named> | ||||
707 | read or write method. | ||||
708 | |||||
709 | =item B<< $attr->get_read_method_ref >> | ||||
710 | |||||
711 | =item B<< $attr->get_write_method_ref >> | ||||
712 | |||||
713 | Returns the subroutine reference of a method suitable for reading or | ||||
714 | writing the attribute's value in the associated class. These methods | ||||
715 | always return a subroutine reference, regardless of whether or not the | ||||
716 | attribute is read- or write-only. | ||||
717 | |||||
718 | =item B<< $attr->insertion_order >> | ||||
719 | |||||
720 | If this attribute has been inserted into a class, this returns a zero | ||||
721 | based index regarding the order of insertion. | ||||
722 | |||||
723 | =back | ||||
724 | |||||
725 | =head2 Informational predicates | ||||
726 | |||||
727 | These 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 | |||||
745 | This will be I<false> if the C<init_arg> was set to C<undef>. | ||||
746 | |||||
747 | =item B<< $attr->has_default >> | ||||
748 | |||||
749 | This will be I<false> if the C<default> was set to C<undef>, since | ||||
750 | C<undef> is the default C<default> anyway. | ||||
751 | |||||
752 | =item B<< $attr->has_builder >> | ||||
753 | |||||
754 | =item B<< $attr->has_insertion_order >> | ||||
755 | |||||
756 | This will be I<false> if this attribute has not be inserted into a class | ||||
757 | |||||
758 | =back | ||||
759 | |||||
760 | =head2 Value management | ||||
761 | |||||
762 | These methods are basically "back doors" to the instance, and can be | ||||
763 | used to bypass the regular accessors, but still stay within the MOP. | ||||
764 | |||||
765 | These methods are not for general use, and should only be used if you | ||||
766 | really know what you are doing. | ||||
767 | |||||
768 | =over 4 | ||||
769 | |||||
770 | =item B<< $attr->initialize_instance_slot($meta_instance, $instance, $params) >> | ||||
771 | |||||
772 | This method is used internally to initialize the attribute's slot in | ||||
773 | the object C<$instance>. | ||||
774 | |||||
775 | The C<$params> is a hash reference of the values passed to the object | ||||
776 | constructor. | ||||
777 | |||||
778 | It's unlikely that you'll need to call this method yourself. | ||||
779 | |||||
780 | =item B<< $attr->set_value($instance, $value) >> | ||||
781 | |||||
782 | Sets the value without going through the accessor. Note that this | ||||
783 | works even with read-only attributes. | ||||
784 | |||||
785 | =item B<< $attr->set_raw_value($instance, $value) >> | ||||
786 | |||||
787 | Sets the value with no side effects such as a trigger. | ||||
788 | |||||
789 | This doesn't actually apply to Class::MOP attributes, only to subclasses. | ||||
790 | |||||
791 | =item B<< $attr->set_initial_value($instance, $value) >> | ||||
792 | |||||
793 | Sets the value without going through the accessor. This method is only | ||||
794 | called when the instance is first being initialized. | ||||
795 | |||||
796 | =item B<< $attr->get_value($instance) >> | ||||
797 | |||||
798 | Returns the value without going through the accessor. Note that this | ||||
799 | works even with write-only accessors. | ||||
800 | |||||
801 | =item B<< $sttr->get_raw_value($instance) >> | ||||
802 | |||||
803 | Returns the value without any side effects such as lazy attributes. | ||||
804 | |||||
805 | Doesn't actually apply to Class::MOP attributes, only to subclasses. | ||||
806 | |||||
807 | =item B<< $attr->has_value($instance) >> | ||||
808 | |||||
809 | Return a boolean indicating whether the attribute has been set in | ||||
810 | C<$instance>. This how the default C<predicate> method works. | ||||
811 | |||||
812 | =item B<< $attr->clear_value($instance) >> | ||||
813 | |||||
814 | This will clear the attribute's value in C<$instance>. This is what | ||||
815 | the default C<clearer> calls. | ||||
816 | |||||
817 | Note that this works even if the attribute does not have any | ||||
818 | associated read, write or clear methods. | ||||
819 | |||||
820 | =back | ||||
821 | |||||
822 | =head2 Class association | ||||
823 | |||||
824 | These methods allow you to manage the attributes association with | ||||
825 | the class that contains it. These methods should not be used | ||||
826 | lightly, nor are they very magical, they are mostly used internally | ||||
827 | and by metaclass instances. | ||||
828 | |||||
829 | =over 4 | ||||
830 | |||||
831 | =item B<< $attr->associated_class >> | ||||
832 | |||||
833 | This returns the C<Class::MOP::Class> with which this attribute is | ||||
834 | associated, if any. | ||||
835 | |||||
836 | =item B<< $attr->attach_to_class($metaclass) >> | ||||
837 | |||||
838 | This method stores a weakened reference to the C<$metaclass> object | ||||
839 | internally. | ||||
840 | |||||
841 | This method does not remove the attribute from its old class, | ||||
842 | nor does it create any accessors in the new class. | ||||
843 | |||||
844 | It is probably best to use the L<Class::MOP::Class> C<add_attribute> | ||||
845 | method instead. | ||||
846 | |||||
847 | =item B<< $attr->detach_from_class >> | ||||
848 | |||||
849 | This method removes the associate metaclass object from the attribute | ||||
850 | it has one. | ||||
851 | |||||
852 | This method does not remove the attribute itself from the class, or | ||||
853 | remove its accessors. | ||||
854 | |||||
855 | It is probably best to use the L<Class::MOP::Class> | ||||
856 | C<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 | |||||
866 | Accessor methods are generated using an accessor metaclass. By | ||||
867 | default, this is L<Class::MOP::Method::Accessor>. This method returns | ||||
868 | the name of the accessor metaclass that this attribute uses. | ||||
869 | |||||
870 | =item B<< $attr->associate_method($method) >> | ||||
871 | |||||
872 | This associates a L<Class::MOP::Method> object with the | ||||
873 | attribute. Typically, this is called internally when an attribute | ||||
874 | generates its accessors. | ||||
875 | |||||
876 | =item B<< $attr->associated_methods >> | ||||
877 | |||||
878 | This returns the list of methods which have been associated with the | ||||
879 | attribute. | ||||
880 | |||||
881 | =item B<< $attr->install_accessors >> | ||||
882 | |||||
883 | This method generates and installs code the attributes various | ||||
884 | accessors. It is typically called from the L<Class::MOP::Class> | ||||
885 | C<add_attribute> method. | ||||
886 | |||||
887 | =item B<< $attr->remove_accessors >> | ||||
888 | |||||
889 | This method removes all of the accessors associated with the | ||||
890 | attribute. | ||||
891 | |||||
892 | This does not currently remove methods from the list returned by | ||||
893 | C<associated_methods>. | ||||
894 | |||||
895 | =back | ||||
896 | |||||
897 | =head2 Introspection | ||||
898 | |||||
899 | =over 4 | ||||
900 | |||||
901 | =item B<< Class::MOP::Attribute->meta >> | ||||
902 | |||||
903 | This will return a L<Class::MOP::Class> instance for this class. | ||||
904 | |||||
905 | It should also be noted that L<Class::MOP> will actually bootstrap | ||||
906 | this module by installing a number of attribute meta-objects into its | ||||
907 | metaclass. | ||||
908 | |||||
909 | =back | ||||
910 | |||||
911 | =head1 AUTHORS | ||||
912 | |||||
913 | Stevan Little E<lt>stevan@iinteractive.comE<gt> | ||||
914 | |||||
915 | =head1 COPYRIGHT AND LICENSE | ||||
916 | |||||
917 | Copyright 2006-2010 by Infinity Interactive, Inc. | ||||
918 | |||||
919 | L<http://www.iinteractive.com> | ||||
920 | |||||
921 | This library is free software; you can redistribute it and/or modify | ||||
922 | it under the same terms as Perl itself. | ||||
923 | |||||
924 | =cut | ||||
925 | |||||
926 |