make_accessor, make_ro_accessor, make_rw_accessor
[gitmo/MooseX-Emulate-Class-Accessor-Fast.git] / lib / MooseX / Emulate / Class / Accessor / Fast.pm
index 154aabf..f87ca44 100644 (file)
@@ -2,7 +2,7 @@ package MooseX::Emulate::Class::Accessor::Fast;
 
 use Moose::Role;
 
-our $VERSION = '0.00100';
+our $VERSION = '0.00400';
 
 =head1 NAME
 
@@ -12,7 +12,7 @@ MooseX::Emulate::Class::Accessor::Fast -
 =head1 SYNOPSYS
 
     package MyClass;
-    Use Moose;
+    use Moose;
 
     with 'MooseX::Emulate::Class::Accessor::Fast';
 
@@ -60,6 +60,26 @@ methods in L<Class::MOP::Attribute>. Example
 
 =head1 METHODS
 
+=head2 BUILD $self %args
+
+Change the default Moose class building to emulate the behavior of C::A::F and
+store arguments in the instance hashref.
+
+=cut
+
+sub BUILD {
+  my $self = shift;
+  my %args;
+  if (scalar @_ == 1 && defined $_[0] && ref($_[0]) eq 'HASH') {
+    %args = %{$_[0]};
+  } elsif( scalar(@_) ) {
+    %args = @_;
+  }
+  my @extra = grep { !exists($self->{$_}) } keys %args;
+  @{$self}{@extra} = @args{@extra};
+  return $self;
+}
+
 =head2 mk_accessors @field_names
 
 Create read-write accessors. An attribute named C<$field_name> will be created.
@@ -77,17 +97,23 @@ sub mk_accessors{
   for my $attr_name (@_){
     my $reader = $self->accessor_name_for($attr_name);
     my $writer = $self->mutator_name_for( $attr_name);
+
     #dont overwrite existing methods
-    my @opts = $reader eq $writer ?
-      ( $self->can($reader) ? () : (accessor => $reader) ) :
-        (
-         ( $self->can($reader) ? () : (reader => $reader) ),
-         ( $self->can($writer) ? () : (writer => $writer) ),
-        );
-    $meta->add_attribute($attr_name, @opts);
-
-    $meta->add_method("_${attr_name}_accessor", $self->can($reader) )
-      if($reader eq $attr_name && !$self->can("_${attr_name}_accessor") );
+    if($reader eq $writer){
+      my %opts = ( $self->can($reader) ? () : (accessor => $reader) );
+      my $attr = $meta->add_attribute($attr_name, %opts);
+      if($attr_name eq $reader){
+        my $alias = "_${attr_name}_accessor";
+        next if $self->can($alias);
+        my @alias_method = $opts{accessor} ? ( $alias => $self->can($reader) )
+          : ( $attr->process_accessors(accessor => $alias, 0 ) );
+        $meta->add_method(@alias_method);
+      }
+    } else {
+      my @opts = ( $self->can($writer) ? () : (writer => $writer) );
+      push(@opts, (reader => $reader)) unless $self->can($reader);
+      $meta->add_attribute($attr_name, @opts);
+    }
   }
 }
 
@@ -102,10 +128,12 @@ sub mk_ro_accessors{
   my $meta = $self->meta;
   for my $attr_name (@_){
     my $reader = $self->accessor_name_for($attr_name);
-    $meta->add_attribute($attr_name,
-                         $self->can($reader) ? () : (reader => $reader) );
-    $meta->add_method("_${attr_name}_accessor", $meta->find_method_by_name($reader))
-      if($reader eq $attr_name && !$self->can("_${attr_name}_accessor") );
+    my @opts = ($self->can($reader) ? () : (reader => $reader) );
+    my $attr = $meta->add_attribute($attr_name, @opts);
+    if($reader eq $attr_name && $reader eq $self->mutator_name_for($attr_name)){
+      $meta->add_method("_${attr_name}_accessor" => $attr->get_read_method_ref)
+        unless $self->can("_${attr_name}_accessor");
+    }
   }
 }
 
@@ -121,9 +149,12 @@ sub mk_wo_accessors{
   my $meta = $self->meta;
   for my $attr_name (@_){
     my $writer = $self->mutator_name_for($attr_name);
-    $meta->add_attribute($attr_name, $self->can($writer) ? () : (writer => $writer) );
-    $meta->add_method("_${attr_name}_accessor", $meta->find_method_by_name($writer))
-      if($writer eq $attr_name && !$self->can("_${attr_name}_accessor") );
+    my @opts = ($self->can($writer) ? () : (writer => $writer) );
+    my $attr = $meta->add_attribute($attr_name, @opts);
+    if($writer eq $attr_name && $writer eq $self->accessor_name_for($attr_name)){
+      $meta->add_method("_${attr_name}_accessor" => $attr->get_write_method_ref)
+        unless $self->can("_${attr_name}_accessor");
+    }
   }
 }
 
@@ -195,6 +226,36 @@ sub get{
   return @values;
 }
 
+sub make_accessor {
+  my($class, $field) = @_;
+  my $meta = $class->meta;
+  my $attr = $meta->find_attribute_by_name($field) || $meta->add_attribute($field); 
+  my $reader = $attr->get_read_method_ref;
+  my $writer = $attr->get_write_method_ref;
+  return sub {
+    my $self = shift;
+    return $self->$reader unless @_;
+    return $self->$writer((@_ > 1 ? [@_] : @_));
+  }
+}
+
+
+sub make_ro_accessor {
+  my($class, $field) = @_;
+  my $meta = $class->meta;
+  my $attr = $meta->find_attribute_by_name($field) || $meta->add_attribute($field); 
+  return $attr->get_read_method_ref;
+}
+
+
+sub make_wo_accessor {
+  my($class, $field) = @_;
+  my $meta = $class->meta;
+  my $attr = $meta->find_attribute_by_name($field) || $meta->add_attribute($field); 
+  return $attr->get_write_method_ref;
+}
+
+
 1;
 
 =head2 meta
@@ -208,9 +269,17 @@ See L<Moose::Meta::Class>.
 L<Moose>, L<Moose::Meta::Attribute>, L<Class::Accessor>, L<Class::Accessor::Fast>,
 L<Class::MOP::Attribute>, L<MooseX::Adopt::Class::Accessor::Fast>
 
-=head1 AUTHOR
+=head1 AUTHORS
+
+Guillermo Roditi (groditi) E<lt>groditi@cpan.orgE<gt>
+
+With contributions from:
+
+=over 4
+
+=item Tomas Doran E<lt>bobtfish@bobtfish.netE<gt>
 
-Guillermo Roditi (groditi) <groditi@cpan.org>
+=back
 
 =head1 LICENSE