Profile of Class/MOP/Attribute.pm

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

Filename | /2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/x86_64-linux/Class/MOP/Attribute.pm
Statements | Executed 14621 statements in 37.0ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
254 | 5 | 2 | 5.91ms | 66.3ms | Class::MOP::Attribute::::_process_accessorsClass::MOP::Attribute::_process_accessors
207 | 3 | 2 | 4.90ms | 90.2ms | Class::MOP::Attribute::::install_accessorsClass::MOP::Attribute::install_accessors
403 | 2 | 2 | 3.30ms | 12.3ms | Class::MOP::Attribute::::_inline_instance_setClass::MOP::Attribute::_inline_instance_set
376 | 2 | 1 | 3.21ms | 5.07ms | Class::MOP::Attribute::::_set_initial_slot_valueClass::MOP::Attribute::_set_initial_slot_value
197 | 1 | 1 | 3.01ms | 53.2ms | Class::MOP::Attribute::::__ANON__[:398]Class::MOP::Attribute::__ANON__[:398]
448 | 1 | 1 | 2.45ms | 8.84ms | Class::MOP::Attribute::::initialize_instance_slotClass::MOP::Attribute::initialize_instance_slot
254 | 2 | 1 | 2.32ms | 2.78ms | Class::MOP::Attribute::::_accessor_descriptionClass::MOP::Attribute::_accessor_description
131 | 50 | 4 | 1.83ms | 4.18ms | Class::MOP::Attribute::::newClass::MOP::Attribute::new
402 | 5 | 3 | 1.21ms | 13.5ms | Class::MOP::Attribute::::_inline_set_valueClass::MOP::Attribute::_inline_set_value
123 | 1 | 1 | 1.19ms | 1.84ms | Class::MOP::Attribute::::_newClass::MOP::Attribute::_new
442 | 1 | 1 | 1.05ms | 1.31ms | Class::MOP::Attribute::::slotsClass::MOP::Attribute::slots
131 | 1 | 1 | 884µs | 1.19ms | Class::MOP::Attribute::::attach_to_classClass::MOP::Attribute::attach_to_class
84 | 2 | 2 | 783µs | 3.62ms | Class::MOP::Attribute::::_inline_instance_getClass::MOP::Attribute::_inline_instance_get
254 | 2 | 1 | 572µs | 572µs | Class::MOP::Attribute::::associate_methodClass::MOP::Attribute::associate_method
245 | 2 | 1 | 291µs | 291µs | Class::MOP::Attribute::::accessor_metaclassClass::MOP::Attribute::accessor_metaclass
75 | 2 | 1 | 268µs | 3.45ms | Class::MOP::Attribute::::_inline_get_valueClass::MOP::Attribute::_inline_get_value
17 | 2 | 2 | 181µs | 348µs | Class::MOP::Attribute::::_inline_instance_hasClass::MOP::Attribute::_inline_instance_has
12 | 1 | 1 | 126µs | 307µs | Class::MOP::Attribute::::get_raw_valueClass::MOP::Attribute::get_raw_value
12 | 1 | 1 | 115µs | 274µs | Class::MOP::Attribute::::has_valueClass::MOP::Attribute::has_value
16 | 1 | 1 | 66µs | 392µs | Class::MOP::Attribute::::_inline_has_valueClass::MOP::Attribute::_inline_has_value
4 | 1 | 1 | 41µs | 138µs | Class::MOP::Attribute::::set_initial_valueClass::MOP::Attribute::set_initial_value
12 | 1 | 1 | 33µs | 339µs | Class::MOP::Attribute::::get_valueClass::MOP::Attribute::get_value
1 | 1 | 1 | 10µs | 10µs | Class::MOP::Attribute::::BEGIN@3Class::MOP::Attribute::BEGIN@3
1 | 1 | 1 | 9µs | 15µs | Class::MOP::Attribute::::BEGIN@10Class::MOP::Attribute::BEGIN@10
1 | 1 | 1 | 9µs | 30µs | Class::MOP::Attribute::::BEGIN@11Class::MOP::Attribute::BEGIN@11
1 | 1 | 1 | 8µs | 54µs | Class::MOP::Attribute::::BEGIN@15Class::MOP::Attribute::BEGIN@15
1 | 1 | 1 | 8µs | 132µs | Class::MOP::Attribute::::BEGIN@19Class::MOP::Attribute::BEGIN@19
1 | 1 | 1 | 8µs | 35µs | Class::MOP::Attribute::::BEGIN@16Class::MOP::Attribute::BEGIN@16
1 | 1 | 1 | 7µs | 39µs | Class::MOP::Attribute::::BEGIN@17Class::MOP::Attribute::BEGIN@17
1 | 1 | 1 | 5µs | 5µs | Class::MOP::Attribute::::BEGIN@13Class::MOP::Attribute::BEGIN@13
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::__ANON__[:169]Class::MOP::Attribute::__ANON__[:169]
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::__ANON__[:198]Class::MOP::Attribute::__ANON__[:198]
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::__ANON__[:218]Class::MOP::Attribute::__ANON__[:218]
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::__ANON__[:401]Class::MOP::Attribute::__ANON__[:401]
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::__ANON__[:456]Class::MOP::Attribute::__ANON__[:456]
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::_inline_clear_valueClass::MOP::Attribute::_inline_clear_value
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::_inline_instance_clearClass::MOP::Attribute::_inline_instance_clear
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::_make_initializer_writer_callbackClass::MOP::Attribute::_make_initializer_writer_callback
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::clear_valueClass::MOP::Attribute::clear_value
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::detach_from_classClass::MOP::Attribute::detach_from_class
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::get_read_methodClass::MOP::Attribute::get_read_method
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::get_read_method_refClass::MOP::Attribute::get_read_method_ref
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::get_write_methodClass::MOP::Attribute::get_write_method
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::get_write_method_refClass::MOP::Attribute::get_write_method_ref
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::remove_accessorsClass::MOP::Attribute::remove_accessors
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::set_raw_valueClass::MOP::Attribute::set_raw_value
0 | 0 | 0 | 0s | 0s | Class::MOP::Attribute::::set_valueClass::MOP::Attribute::set_value

Call graph for these subroutines as a Graphviz dot language file.

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