making get_read_method, etc act more sanely
Stevan Little [Mon, 26 Nov 2007 21:38:35 +0000 (21:38 +0000)]
Changes
MANIFEST
README
lib/Class/MOP.pm
lib/Class/MOP/Attribute.pm
t/022_attribute_duplication.t
t/023_attribute_get_read_write.t [new file with mode: 0644]

diff --git a/Changes b/Changes
index 4ec3cdc..53a89ec 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,12 @@
 Revision history for Perl extension Class-MOP.
 
+0.48
+    * Class::MOP::Attribute
+      - fixed get_read/write_method to handle the 
+        HASH ref case, which makes the 
+        get_read/write_method_ref handle it too.
+        - added more tests for this
+
 0.47 Sat. Nov. 24, 2007
     * Class::MOP::Attribute
       - fixed misspelling in get_write_method_ref
index bf8da30..5f2b5b4 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -55,6 +55,7 @@ t/019_anon_class_keep_alive.t
 t/020_attribute.t
 t/021_attribute_errors_and_edge_cases.t
 t/022_attribute_duplication.t
+t/023_attribute_get_read_write.t
 t/030_method.t
 t/031_method_modifiers.t
 t/040_metaclass.t
diff --git a/README b/README
index e44b3af..208c8a3 100644 (file)
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-Class::MOP version 0.46
+Class::MOP version 0.48
 ===========================
 
 See the individual module documentation for more information
index 474ae18..7b037be 100644 (file)
@@ -13,7 +13,7 @@ use Class::MOP::Method;
 
 use Class::MOP::Immutable;
 
-our $VERSION   = '0.47';
+our $VERSION   = '0.48';
 our $AUTHORITY = 'cpan:STEVAN';
 
 {
index 32931a9..1b721d7 100644 (file)
@@ -9,7 +9,7 @@ use Class::MOP::Method::Accessor;
 use Carp         'confess';
 use Scalar::Util 'blessed', 'reftype', 'weaken';
 
-our $VERSION   = '0.19';
+our $VERSION   = '0.20';
 our $AUTHORITY = 'cpan:STEVAN';
 
 use base 'Class::MOP::Object';
@@ -133,8 +133,25 @@ sub init_arg  { $_[0]->{'$!init_arg'}  }
 # end bootstrapped away method section.
 # (all methods below here are kept intact)
 
-sub get_read_method  { $_[0]->reader || $_[0]->accessor }
-sub get_write_method { $_[0]->writer || $_[0]->accessor }
+sub get_read_method  { 
+    my $self   = shift;    
+    my $reader = $self->reader || $self->accessor;
+    # normal case ...
+    return $reader unless ref $reader;
+    # the HASH ref case
+    my ($name) = %$reader;
+    return $name;
+}
+
+sub get_write_method { 
+    my $self   = shift;
+    my $writer = $self->writer || $self->accessor; 
+    # normal case ...
+    return $writer unless ref $writer;
+    # the HASH ref case
+    my ($name) = %$writer;
+    return $name;    
+}
 
 sub get_read_method_ref {
     my $self = shift;
@@ -148,7 +165,7 @@ sub get_read_method_ref {
 
 sub get_write_method_ref {
     my $self = shift;    
-    if ((my $writer = $self->get_write_method) && $self->associated_class) {    
+    if ((my $writer = $self->get_write_method) && $self->associated_class) {         
         return $self->associated_class->get_method($writer);
     }
     else {
index 50d4b22..b324658 100644 (file)
@@ -5,7 +5,7 @@ use warnings;
 
 use Scalar::Util;
 
-use Test::More tests => 32;
+use Test::More tests => 17;
 
 BEGIN {
     use_ok('Class::MOP');
@@ -36,24 +36,7 @@ one first.
     
     ::is($bar_attr->reader, 'get_bar', '... the bar attribute has the reader get_bar');
     ::is($bar_attr->writer, 'set_bar', '... the bar attribute has the writer set_bar');    
-    ::is($bar_attr->associated_class, Foo->meta, '... and the bar attribute is associated with Foo->meta');
-    
-    ::is($bar_attr->get_read_method,  'get_bar', '... $attr does have an read method');
-    ::is($bar_attr->get_write_method, 'set_bar', '... $attr does have an write method');    
-    
-    {
-        my $reader = $bar_attr->get_read_method_ref;
-        my $writer = $bar_attr->get_write_method_ref;        
-        
-        ::isa_ok($reader, 'Class::MOP::Method');
-        ::isa_ok($writer, 'Class::MOP::Method');        
-
-        ::is($reader->fully_qualified_name, 'Foo::get_bar', '... it is the sub we are looking for');
-        ::is($writer->fully_qualified_name, 'Foo::set_bar', '... it is the sub we are looking for');
-        
-        ::is(Scalar::Util::reftype($reader->body), 'CODE', '... it is a plain old sub');
-        ::is(Scalar::Util::reftype($writer->body), 'CODE', '... it is a plain old sub');                
-    }    
+    ::is($bar_attr->associated_class, Foo->meta, '... and the bar attribute is associated with Foo->meta'); 
     
     Foo->meta->add_attribute('bar' => 
         reader => 'assign_bar'
@@ -64,23 +47,7 @@ one first.
     ::can_ok('Foo', 'assign_bar');    
     ::ok(Foo->meta->has_attribute('bar'), '... Foo still has the attribute bar');
     
-    my $bar_attr2 = Foo->meta->get_attribute('bar');
-    
-    ::is($bar_attr2->get_read_method,  'assign_bar', '... $attr does have an read method');
-    ::ok(!$bar_attr2->get_write_method, '... $attr does have an write method');    
-    
-    {
-        my $reader = $bar_attr2->get_read_method_ref;
-        my $writer = $bar_attr2->get_write_method_ref;        
-        
-        ::isa_ok($reader, 'Class::MOP::Method');
-        ::ok(!Scalar::Util::blessed($writer), '... the writer method is not blessed though');    
-        
-        ::is($reader->fully_qualified_name, 'Foo::assign_bar', '... it is the sub we are looking for');            
-        
-        ::is(Scalar::Util::reftype($reader->body), 'CODE', '... it is a plain old sub');
-        ::is(Scalar::Util::reftype($writer), 'CODE', '... it is a plain old sub');                
-    }    
+    my $bar_attr2 = Foo->meta->get_attribute('bar');  
     
     ::isnt($bar_attr, $bar_attr2, '... this is a new bar attribute');
     ::isnt($bar_attr->associated_class, Foo->meta, '... and the old bar attribute is no longer associated with Foo->meta');    
diff --git a/t/023_attribute_get_read_write.t b/t/023_attribute_get_read_write.t
new file mode 100644 (file)
index 0000000..f5faa90
--- /dev/null
@@ -0,0 +1,106 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Scalar::Util 'blessed', 'reftype';
+
+use Test::More tests => 35;
+
+BEGIN {
+    use_ok('Class::MOP');
+}
+
+=pod
+
+This checks the get_read/write_method
+and get_read/write_method_ref methods
+
+=cut
+
+{
+    package Foo;
+    use metaclass;
+    
+    Foo->meta->add_attribute('bar' => 
+        reader => 'get_bar',
+        writer => 'set_bar',
+    );  
+    
+    Foo->meta->add_attribute('baz' => 
+        accessor => 'baz',
+    );  
+    
+    Foo->meta->add_attribute('gorch' => 
+        reader => { 'get_gorch', => sub { (shift)->{gorch} } }
+    );       
+}
+
+can_ok('Foo', 'get_bar');
+can_ok('Foo', 'set_bar');    
+can_ok('Foo', 'baz');    
+can_ok('Foo', 'get_gorch');    
+
+ok(Foo->meta->has_attribute('bar'), '... Foo has the attribute bar');
+ok(Foo->meta->has_attribute('baz'), '... Foo has the attribute baz');
+ok(Foo->meta->has_attribute('gorch'), '... Foo has the attribute gorch');
+
+my $bar_attr = Foo->meta->get_attribute('bar');
+my $baz_attr = Foo->meta->get_attribute('baz');
+my $gorch_attr = Foo->meta->get_attribute('gorch');
+
+is($bar_attr->reader, 'get_bar', '... the bar attribute has the reader get_bar');
+is($bar_attr->writer, 'set_bar', '... the bar attribute has the writer set_bar');    
+is($bar_attr->associated_class, Foo->meta, '... and the bar attribute is associated with Foo->meta');
+
+is($bar_attr->get_read_method,  'get_bar', '... $attr does have an read method');
+is($bar_attr->get_write_method, 'set_bar', '... $attr does have an write method');    
+
+{
+    my $reader = $bar_attr->get_read_method_ref;
+    my $writer = $bar_attr->get_write_method_ref;        
+    
+    isa_ok($reader, 'Class::MOP::Method');
+    isa_ok($writer, 'Class::MOP::Method');        
+    
+    is($reader->fully_qualified_name, 'Foo::get_bar', '... it is the sub we are looking for');
+    is($writer->fully_qualified_name, 'Foo::set_bar', '... it is the sub we are looking for');
+    
+    is(reftype($reader->body), 'CODE', '... it is a plain old sub');
+    is(reftype($writer->body), 'CODE', '... it is a plain old sub');                
+}
+
+is($baz_attr->accessor, 'baz', '... the bar attribute has the accessor baz');
+is($baz_attr->associated_class, Foo->meta, '... and the bar attribute is associated with Foo->meta');
+
+is($baz_attr->get_read_method,  'baz', '... $attr does have an read method');
+is($baz_attr->get_write_method, 'baz', '... $attr does have an write method');    
+
+{
+    my $reader = $baz_attr->get_read_method_ref;
+    my $writer = $baz_attr->get_write_method_ref;        
+    
+    isa_ok($reader, 'Class::MOP::Method');
+    isa_ok($writer, 'Class::MOP::Method');  
+    
+    is($reader, $writer, '... they are the same method');      
+    
+    is($reader->fully_qualified_name, 'Foo::baz', '... it is the sub we are looking for');
+    is($writer->fully_qualified_name, 'Foo::baz', '... it is the sub we are looking for');              
+}
+
+is(ref($gorch_attr->reader), 'HASH', '... the gorch attribute has the reader get_gorch (HASH ref)');
+is($gorch_attr->associated_class, Foo->meta, '... and the gorch attribute is associated with Foo->meta');
+
+is($gorch_attr->get_read_method,  'get_gorch', '... $attr does have an read method');
+ok(!$gorch_attr->get_write_method, '... $attr does not have an write method');    
+
+{
+    my $reader = $gorch_attr->get_read_method_ref;
+    my $writer = $gorch_attr->get_write_method_ref;        
+    
+    isa_ok($reader, 'Class::MOP::Method');
+    ok(!blessed($writer), '... it is not a plain old sub'); 
+    
+    is($reader->fully_qualified_name, 'Foo::get_gorch', '... it is the sub we are looking for');
+}