fixed all the attribute name to be more Perl6ish and then removed the : in the init_a...
[gitmo/Class-MOP.git] / examples / AttributesWithHistory.pod
index fe712c8..6365e79 100644 (file)
@@ -5,44 +5,66 @@ package # hide the package from PAUSE
 use strict;
 use warnings;
 
-our $VERSION = '0.02';
+our $VERSION = '0.05';
 
 use base 'Class::MOP::Attribute';
 
 # this is for an extra attribute constructor 
 # option, which is to be able to create a 
 # way for the class to access the history
-__PACKAGE__->meta->add_attribute(
-    Class::MOP::Attribute->new('history_accessor' => (
-        reader    => 'history_accessor',
-        init_arg  => 'history_accessor',
-        predicate => 'has_history_accessor',
-    ))
-);
+AttributesWithHistory->meta->add_attribute('$!history_accessor' => (
+    reader    => 'history_accessor',
+    init_arg  => 'history_accessor',
+    predicate => 'has_history_accessor',
+));
 
 # this is a place to store the actual 
 # history of the attribute
-__PACKAGE__->meta->add_attribute(
-    Class::MOP::Attribute->new('_history' => (
-        accessor => '_history',
-        default  => sub { [] },
-    ))
-);
+AttributesWithHistory->meta->add_attribute('$!_history' => (
+    accessor => '_history',
+    default  => sub { {} },
+));
+
+sub accessor_metaclass { 'AttributesWithHistory::Method::Accessor' }
+
+AttributesWithHistory->meta->add_after_method_modifier('install_accessors' => sub {
+    my ($self) = @_;
+    # and now add the history accessor
+    $self->associated_class->add_method(
+        $self->process_accessors('history_accessor' => $self->history_accessor())
+    ) if $self->has_history_accessor();
+});
+
+package # hide the package from PAUSE
+    AttributesWithHistory::Method::Accessor;
+
+use strict;
+use warnings;
+
+our $VERSION = '0.01';
+
+use base 'Class::MOP::Method::Accessor';
 
 # generate the methods
 
 sub generate_history_accessor_method {
-    my ($self, $attr_name) = @_; 
+    my $attr_name = (shift)->associated_attribute->name;
     eval qq{sub {
-        \@\{\$_[0]->meta->get_attribute('$attr_name')->_history()\};        
+        unless (ref \$_[0]->meta->get_attribute('$attr_name')->_history()->\{\$_[0]\}) \{
+            \$_[0]->meta->get_attribute('$attr_name')->_history()->\{\$_[0]\} = [];    
+        \}
+        \@\{\$_[0]->meta->get_attribute('$attr_name')->_history()->\{\$_[0]\}\};        
     }};    
 }
 
 sub generate_accessor_method {
-    my ($self, $attr_name) = @_;
+    my $attr_name = (shift)->associated_attribute->name;
     eval qq{sub {
         if (scalar(\@_) == 2) {
-            push \@\{\$_[0]->meta->get_attribute('$attr_name')->_history()\} => \$_[1];
+            unless (ref \$_[0]->meta->get_attribute('$attr_name')->_history()->\{\$_[0]\}) \{
+                \$_[0]->meta->get_attribute('$attr_name')->_history()->\{\$_[0]\} = [];    
+            \}            
+            push \@\{\$_[0]->meta->get_attribute('$attr_name')->_history()->\{\$_[0]\}\} => \$_[1];
             \$_[0]->{'$attr_name'} = \$_[1];
         }
         \$_[0]->{'$attr_name'};
@@ -50,23 +72,15 @@ sub generate_accessor_method {
 }
 
 sub generate_writer_method {
-    my ($self, $attr_name) = @_; 
+    my $attr_name = (shift)->associated_attribute->name;
     eval qq{sub {
-        push \@\{\$_[0]->meta->get_attribute('$attr_name')->_history()\} => \$_[1];        
+        unless (ref \$_[0]->meta->get_attribute('$attr_name')->_history()->\{\$_[0]\}) \{
+            \$_[0]->meta->get_attribute('$attr_name')->_history()->\{\$_[0]\} = [];    
+        \}        
+        push \@\{\$_[0]->meta->get_attribute('$attr_name')->_history()->\{\$_[0]\}\} => \$_[1];        
         \$_[0]->{'$attr_name'} = \$_[1];
     }};
-}
-
-sub install_accessors {
-    my $self = shift;
-    # do as we normall do ...
-    $self->SUPER::install_accessors();
-    # and now add the history accessor
-    $self->associated_class->add_method(
-        $self->process_accessors('history_accessor' => $self->history_accessor())
-    ) if $self->has_history_accessor();
-    return;
-}
+}    
 
 1;
 
@@ -80,8 +94,6 @@ AttributesWithHistory - An example attribute metaclass which keeps a history of
   
   package Foo;
   
-  use Class::MOP 'meta';
-  
   Foo->meta->add_attribute(AttributesWithHistory->new('foo' => (
       accessor         => 'foo',
       history_accessor => 'get_foo_history',
@@ -95,7 +107,7 @@ AttributesWithHistory - An example attribute metaclass which keeps a history of
   
   sub new  {
       my $class = shift;
-      bless $class->meta->construct_instance(@_) => $class;
+      $class->meta->new_object(@_);
   }
   
 =head1 DESCRIPTION
@@ -106,10 +118,12 @@ history as a field in the attribute meta-object, and will
 autogenerate a means of accessing that history for the class 
 which these attributes are added too.
 
-=head1 AUTHOR
+=head1 AUTHORS
 
 Stevan Little E<lt>stevan@iinteractive.comE<gt>
 
+Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
+
 =head1 COPYRIGHT AND LICENSE
 
 Copyright 2006 by Infinity Interactive, Inc.