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
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
=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
use strict;
use warnings;
-use Test::More tests => 7;
+use Test::More tests => 16;
BEGIN {
use_ok('Moose');
extends 'Bar';
+ override bar => sub { 'Baz::bar -> ' . super() };
override baz => sub { 'Baz::baz -> ' . super() };
}
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
use strict;
use warnings;
-use Test::More tests => 7;
+use Test::More tests => 16;
BEGIN {
use_ok('Moose');
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;
extends 'Foo';
- augment foo => sub { 'Bar::foo(' . inner() . ')' };
+ augment foo => sub { 'Bar::foo(' . (inner() || '') . ')' };
augment bar => sub { 'Bar::bar' };
package Baz;
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();
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');