whoot
Stevan Little [Fri, 24 Mar 2006 04:00:29 +0000 (04:00 +0000)]
Changes
lib/Moose.pm
t/012_super_and_override.t
t/013_inner_and_augment.t

diff --git a/Changes b/Changes
index c4f1da8..bd068e0 100644 (file)
--- a/Changes
+++ b/Changes
@@ -6,6 +6,8 @@ Revision history for Perl extension Moose
         it now captures errors and deals with inline 
         packages correctly (bug found by mst, solution 
         stolen from alias)
+      - added super/override & inner/augment features
+        - added tests and docs for these
     
     * Moose::Object
       - BUILDALL now takes a reference of the %params 
index 58d431d..68d44dc 100644 (file)
@@ -327,6 +327,32 @@ This three items are syntactic sugar for the before, after and around method
 modifier features that L<Class::MOP> provides. More information on these can 
 be found in the L<Class::MOP> documentation for now. 
 
+=item B<super>
+
+The keyword C<super> is a noop when called outside of an C<override> method. In 
+the context of an C<override> method, it will call the next most appropriate 
+superclass method with the same arguments as the original method.
+
+=item B<override ($name, &sub)>
+
+An C<override> method, is a way of explictly saying "I am overriding this 
+method from my superclass". You can call C<super> within this method, and 
+it will work as expected. The same thing I<can> be accomplished with a normal 
+method call and the C<SUPER::> pseudo-package, it is really your choice. 
+
+=item B<inner>
+
+The keyword C<inner>, much like C<super>, is a no-op outside of the context of 
+an C<augment> method. You can think of C<inner> as being the inverse of 
+C<super>, the details of how C<inner> and C<augment> work is best described in 
+the L<Moose::Cookbook>.
+
+=item B<augment ($name, &sub)>
+
+An C<augment> method, is a way of explictly saying "I am augmenting this 
+method from my superclass". Once again, the details of how C<inner> and 
+C<augment> work is best described in the L<Moose::Cookbook>.
+
 =item B<confess>
 
 This is the C<Carp::confess> function, and exported here beause I use it 
@@ -369,6 +395,12 @@ ideas/feature-requests/encouragement
 
 =item L<http://forum2.org/moose/>
 
+=item L<http://www.cs.utah.edu/plt/publications/oopsla04-gff.pdf>
+
+This paper (suggested by lbr on #moose) was what lead to the implementation 
+of the C<super>/C<overrride> and C<inner>/C<augment> features. If you really 
+want to understand this feature, I suggest you read this.
+
 =back
 
 =head1 BUGS
index a58e3b9..9b5fd9c 100644 (file)
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 7;
+use Test::More tests => 16;
 
 BEGIN {
     use_ok('Moose');           
@@ -35,6 +35,7 @@ BEGIN {
     
     extends 'Bar';
     
+    override bar => sub { 'Baz::bar -> ' . super() };       
     override baz => sub { 'Baz::baz -> ' . super() }; 
 }
 
@@ -44,5 +45,20 @@ isa_ok($baz, 'Bar');
 isa_ok($baz, 'Foo');
 
 is($baz->foo(), 'Foo::foo', '... got the right value from &foo');
-is($baz->bar(), 'Bar::bar -> Foo::bar', '... got the right value from &bar');
+is($baz->bar(), 'Baz::bar -> Bar::bar -> Foo::bar', '... got the right value from &bar');
 is($baz->baz(), 'Baz::baz -> Foo::baz', '... got the right value from &baz');
+
+my $bar = Bar->new();
+isa_ok($bar, 'Bar');
+isa_ok($bar, 'Foo');
+
+is($bar->foo(), 'Foo::foo', '... got the right value from &foo');
+is($bar->bar(), 'Bar::bar -> Foo::bar', '... got the right value from &bar');
+is($bar->baz(), 'Foo::baz', '... got the right value from &baz');
+
+my $foo = Foo->new();
+isa_ok($foo, 'Foo');
+
+is($foo->foo(), 'Foo::foo', '... got the right value from &foo');
+is($foo->bar(), 'Foo::bar', '... got the right value from &bar');
+is($foo->baz(), 'Foo::baz', '... got the right value from &baz');
\ No newline at end of file
index 15a73a5..c1bcaf3 100644 (file)
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 7;
+use Test::More tests => 16;
 
 BEGIN {
     use_ok('Moose');           
@@ -15,9 +15,9 @@ BEGIN {
     use warnings;
     use Moose;
     
-    sub foo { 'Foo::foo(' . inner() . ')' }
-    sub bar { 'Foo::bar(' . inner() . ')' }    
-    sub baz { 'Foo::baz(' . inner() . ')' }        
+    sub foo { 'Foo::foo(' . (inner() || '') . ')' }
+    sub bar { 'Foo::bar(' . (inner() || '') . ')' }    
+    sub baz { 'Foo::baz(' . (inner() || '') . ')' }        
     
     package Bar;
     use strict;
@@ -26,7 +26,7 @@ BEGIN {
     
     extends 'Foo';
     
-    augment foo => sub { 'Bar::foo(' . inner() . ')' };   
+    augment foo => sub { 'Bar::foo(' . (inner() || '') . ')' };   
     augment bar => sub { 'Bar::bar' };       
     
     package Baz;
@@ -38,6 +38,10 @@ BEGIN {
     
     augment foo => sub { 'Baz::foo' }; 
     augment baz => sub { 'Baz::baz' };       
+
+    # this will actually never run, 
+    # because Bar::bar does not call inner()
+    augment bar => sub { 'Baz::bar' };  
 }
 
 my $baz = Baz->new();
@@ -49,3 +53,17 @@ is($baz->foo(), 'Foo::foo(Bar::foo(Baz::foo))', '... got the right value from &f
 is($baz->bar(), 'Foo::bar(Bar::bar)', '... got the right value from &bar');
 is($baz->baz(), 'Foo::baz(Baz::baz)', '... got the right value from &baz');
 
+my $bar = Bar->new();
+isa_ok($bar, 'Bar');
+isa_ok($bar, 'Foo');
+
+is($bar->foo(), 'Foo::foo(Bar::foo())', '... got the right value from &foo');
+is($bar->bar(), 'Foo::bar(Bar::bar)', '... got the right value from &bar');
+is($bar->baz(), 'Foo::baz()', '... got the right value from &baz');
+
+my $foo = Foo->new();
+isa_ok($foo, 'Foo');
+
+is($foo->foo(), 'Foo::foo()', '... got the right value from &foo');
+is($foo->bar(), 'Foo::bar()', '... got the right value from &bar');
+is($foo->baz(), 'Foo::baz()', '... got the right value from &baz');