Implement override/super
[gitmo/Mouse.git] / lib / Mouse.pm
index 97914a6..c55e053 100644 (file)
@@ -21,9 +21,9 @@ use Mouse::Util;
 use Mouse::Meta::Attribute;
 use Mouse::Meta::Class;
 use Mouse::Object;
-use Mouse::TypeRegistry;
+use Mouse::Util::TypeConstraints;
 
-our @EXPORT = qw(extends has before after around blessed confess with);
+our @EXPORT = qw(extends has before after around override super blessed confess with);
 
 sub extends { Mouse::Meta::Class->initialize(caller)->superclasses(@_) }
 
@@ -77,6 +77,36 @@ sub with {
     Mouse::Util::apply_all_roles((caller)[0], @_);
 }
 
+our $SUPER_PACKAGE;
+our $SUPER_BODY;
+our @SUPER_ARGS;
+
+sub super {
+    # This check avoids a recursion loop - see
+    # t/100_bugs/020_super_recursion.t
+    return if defined $SUPER_PACKAGE && $SUPER_PACKAGE ne caller();
+    return unless $SUPER_BODY; $SUPER_BODY->(@SUPER_ARGS);
+}
+
+sub override {
+    my $meta = Mouse::Meta::Class->initialize(caller);
+    my $pkg = $meta->name;
+
+    my $name = shift;
+    my $code = shift;
+
+    my $body = $pkg->can($name)
+        or confess "You cannot override '$name' because it has no super method";
+
+    $meta->add_method($name => sub {
+        local $SUPER_PACKAGE = $pkg;
+        local @SUPER_ARGS = @_;
+        local $SUPER_BODY = $body;
+
+        $code->(@_);
+    });
+}
+
 sub import {
     my $class = shift;
 
@@ -234,6 +264,14 @@ as Mouse unless Moose is loaded, in which case it will act as Moose.
 
 Mouse also has the blessings of Moose's author, stevan.
 
+=head2 MouseX
+
+Please don't copy MooseX code to MouseX. If you need extensions, you really
+should upgrade to Moose. We don't need two parallel sets of extensions!
+
+If you really must write a Mouse extension, please contact the Moose mailing
+list or #moose on IRC beforehand.
+
 =head1 KEYWORDS
 
 =head2 meta -> Mouse::Meta::Class