1 package MooseX::Emulate::Class::Accessor::Fast;
5 our $VERSION = '0.00300';
9 MooseX::Emulate::Class::Accessor::Fast -
10 Emulate Class::Accessor::Fast behavior using Moose attributes
17 with 'MooseX::Emulate::Class::Accessor::Fast';
20 #fields with readers and writers
21 __PACKAGE__->mk_accessors(qw/field1 field2/);
22 #fields with readers only
23 __PACKAGE__->mk_accessors(qw/field3 field4/);
24 #fields with writers only
25 __PACKAGE__->mk_accessors(qw/field5 field6/);
30 This module attempts to emulate the behavior of L<Class::Accessor::Fast> as
31 accurately as possible using the Moose attribute system. The public API of
32 C<Class::Accessor::Fast> is wholly supported, but the private methods are not.
33 If you are only using the public methods (as you should) migration should be a
34 matter of switching your C<use base> line to a C<with> line.
36 While I have attempted to emulate the behavior of Class::Accessor::Fast as closely
37 as possible bugs may still be lurking in edge-cases.
41 Simple documentation is provided here for your convenience, but for more thorough
42 documentation please see L<Class::Accessor::Fast> and L<Class::Accessor>.
44 =head2 A note about introspection
46 Please note that, at this time, the C<is> flag attribute is not being set. To
47 determine the C<reader> and C<writer> methods using introspection in later versions
48 of L<Class::MOP> ( > 0.38) please use the C<get_read_method> and C<get_write_method>
49 methods in L<Class::MOP::Attribute>. Example
51 # with Class::MOP <= 0.38
52 my $attr = $self->meta->find_attribute_by_name($field_name);
53 my $reader_method = $attr->reader || $attr->accessor;
54 my $writer_method = $attr->writer || $attr->accessor;
56 # with Class::MOP > 0.38
57 my $attr = $self->meta->find_attribute_by_name($field_name);
58 my $reader_method = $attr->get_read_method;
59 my $writer_method = $attr->get_write_method;
63 =head2 BUILD $self %args
65 Change the default Moose class building to emulate the behavior of C::A::F and
66 store arguments in the instance hashref.
73 if (scalar @_ == 1 && defined $_[0] && ref($_[0]) eq 'HASH') {
75 } elsif( scalar(@_) ) {
78 my @extra = grep { !exists($self->{$_}) } keys %args;
79 @{$self}{@extra} = @args{@extra};
83 =head2 mk_accessors @field_names
85 Create read-write accessors. An attribute named C<$field_name> will be created.
86 The name of the c<reader> and C<writer> methods will be determined by the return
87 value of C<accessor_name_for> and C<mutator_name_for>, which by default return the
88 name passed unchanged. If the accessor and mutator names are equal the C<accessor>
89 attribute will be passes to Moose, otherwise the C<reader> and C<writer> attributes
90 will be passed. Please see L<Class::MOP::Attribute> for more information.
96 my $meta = $self->meta;
97 for my $attr_name (@_){
98 my $reader = $self->accessor_name_for($attr_name);
99 my $writer = $self->mutator_name_for( $attr_name);
100 #dont overwrite existing methods
101 my @opts = $reader eq $writer ?
102 ( $self->can($reader) ? () : (accessor => $reader) ) :
104 ( $self->can($reader) ? () : (reader => $reader) ),
105 ( $self->can($writer) ? () : (writer => $writer) ),
107 $meta->add_attribute($attr_name, @opts);
109 $meta->add_method("_${attr_name}_accessor", $self->can($reader) )
110 if($reader eq $attr_name && !$self->can("_${attr_name}_accessor") );
114 =head2 mk_ro_accessors @field_names
116 Create read-only accessors.
122 my $meta = $self->meta;
123 for my $attr_name (@_){
124 my $reader = $self->accessor_name_for($attr_name);
125 $meta->add_attribute($attr_name,
126 $self->can($reader) ? () : (reader => $reader) );
127 $meta->add_method("_${attr_name}_accessor", $meta->find_method_by_name($reader))
128 if($reader eq $attr_name && !$self->can("_${attr_name}_accessor") );
132 =head2 mk_ro_accessors @field_names
134 Create write-only accessors.
138 #this is retarded.. but we need it for compatibility or whatever.
141 my $meta = $self->meta;
142 for my $attr_name (@_){
143 my $writer = $self->mutator_name_for($attr_name);
144 $meta->add_attribute($attr_name, $self->can($writer) ? () : (writer => $writer) );
145 $meta->add_method("_${attr_name}_accessor", $meta->find_method_by_name($writer))
146 if($writer eq $attr_name && !$self->can("_${attr_name}_accessor") );
150 =head2 follow_best_practices
152 Preface readers with 'get_' and writers with 'set_'.
153 See original L<Class::Accessor> documentation for more information.
157 sub follow_best_practice{
159 my $meta = $self->meta;
161 $meta->remove_method('mutator_name_for');
162 $meta->remove_method('accessor_name_for');
163 $meta->add_method('mutator_name_for', sub{ return "set_".$_[1] });
164 $meta->add_method('accessor_name_for', sub{ return "get_".$_[1] });
167 =head2 mutator_name_for
169 =head2 accessor_name_for
171 See original L<Class::Accessor> documentation for more information.
175 sub mutator_name_for{ return $_[1] }
176 sub accessor_name_for{ return $_[1] }
180 See original L<Class::Accessor> documentation for more information.
187 confess "Wrong number of arguments received" unless scalar @_;
189 #my $writer = $self->mutator_name_for( $k );
190 confess "No such attribute '$k'"
191 unless ( my $attr = $self->meta->find_attribute_by_name($k) );
192 my $writer = $attr->writer || $attr->accessor;
193 $self->$writer(@_ > 1 ? [@_] : @_);
198 See original L<Class::Accessor> documentation for more information.
204 confess "Wrong number of arguments received" unless scalar @_;
207 #while( my $attr = $self->meta->find_attribute_by_name( shift(@_) ){
209 confess "No such attribute '$_'"
210 unless ( my $attr = $self->meta->find_attribute_by_name($_) );
211 my $reader = $attr->reader || $attr->accessor;
212 @_ > 1 ? push(@values, $self->$reader) : return $self->$reader;
222 See L<Moose::Meta::Class>.
228 L<Moose>, L<Moose::Meta::Attribute>, L<Class::Accessor>, L<Class::Accessor::Fast>,
229 L<Class::MOP::Attribute>, L<MooseX::Adopt::Class::Accessor::Fast>
233 Guillermo Roditi (groditi) E<lt>groditi@cpan.orgE<gt>
235 With contributions from:
239 =item Tomas Doran E<lt>bobtfish@bobtfish.netE<gt>
245 You may distribute this code under the same terms as Perl itself.