# assume that these 2 methods are # defined in some module and then # exported into your classes's # package namespace. sub redefines ($$$) { no strict 'refs'; no warnings 'redefine'; my ($package, $old_name, $new_name) = @_; my ($caller_package) = caller(); $caller_package->isa($package) || die "Can't rename from a package you do not inherit from"; my $old_method = $package->can($old_name); (defined($old_method)) || die "you cannot rename a method you dont have"; my $current_method; if (exists ${"${caller_package}::"}{$old_name}) { $current_method = \&{"${caller_package}::$old_name"}; } else { $current_method = sub { die "Method no implemented" } } *{"${caller_package}::$old_name"} = sub { my $self = shift; my ($_caller_package) = caller(); return $self->$new_name(@_) if ($package->isa($_caller_package)); # or $self->$current_method(@_); }; *{"${caller_package}::$new_name"} = $old_method; } sub next_method { my ($self, $package, @args) = @_; my ($p, $f, $l, $function) = caller(1); $self->isa($package) || die "Can only dispatch on ancestors of $p"; my @module_path = split /\:\:/, $function; my $caller_function = $module_path[-1]; my $dispatch = $package->can($caller_function); return $self->$dispatch(@args); }