mikezone has asked for the wisdom of the Perl Monks concerning the following question:

Is there a mechanism to disinherit an inherited method? Such that $object->can( $disinherited_method ) can't?

Conditions:

my $example = new B; if( $example->can( "a3" ) { $example->a3(); # @$*&%! Still there. } else { print "Successful disinheritence!\n"; }

I've tried messing with Exporter in a bunch of ways, after reading the Camel 3rd ed. Unfortunately I glossed over the part on p889 until after I made a bunch of failed examples. I've tried undef( &A::a3 ), only to be greeted with an error I've not seen before (something like undefined subroutine a3() called at line...). Please, no recommendations to refactor my classes.

Much thanks in advance,
- m.

Replies are listed 'Best First'.
Re: Perl OO Disinheritence
by miyagawa (Chaplain) on Mar 26, 2002 at 08:00 UTC
    Not a direct answer though:
    package B; sub can { my($proto, $method) = @_; return if $method eq 'a3'; $proto->UNIVERSAL::can($method); }

    --
    Tatsuhiko Miyagawa
    miyagawa@cpan.org

Re: Perl OO Disinheritence
by rjray (Chaplain) on Mar 26, 2002 at 08:14 UTC

    This is one of those catches about Perl's OO behavior: since there are no "private" methods, there's no way for class A to hide a3() aside from the tricks in Damian's book. Of course, if the "A" class never meant for a3 to be private, it wouldn't have helped anyway.

    Others have shown the best way to prevent the UNIVERSAL::can method from showing a3 to the outside world. But you'll also want to override it, probably with a null method (or an outright die if you want to be proactive about it):

    sub B::a3 { return; }

    --rjray

Re: Perl OO Disinheritence
by zengargoyle (Deacon) on Mar 26, 2002 at 07:57 UTC

    override UNIVERSAL::can to return undef for the Package B and Method a3 combination.

•Re: Perl OO Disinheritence
by merlyn (Sage) on Mar 26, 2002 at 15:50 UTC
    If it can't "a3", it's not @ISA = qw(A). Sounds to me like you've got a mixed-up class design. Maybe both A and B are subclasses of a common ancestor, where you define what is now a1 and a2 there, then let A and B both inherit from that, where A adds a3, and B defines b1 and b2, and inherits a1 and a2 from the common superclass.

    Hard to tell with so much abstraction. Can you give us the specifics?

    -- Randal L. Schwartz, Perl hacker

Re: Perl OO Disinheritence
by Juerd (Abbot) on Mar 26, 2002 at 18:25 UTC

    * . I don't want Package B to implement method a3( ).

    You could override it. Simple as can be, and very straight forward.

    package B; use base 'A'; use Carp; use strict; sub a3 { croak sprintf q[Can't locate object method "a3" via package "%s"], ref shift; }

    Please, no recommendations to refactor my classes.

    But I really think you should.

    U28geW91IGNhbiBhbGwgcm90MTMgY
    W5kIHBhY2soKS4gQnV0IGRvIHlvdS
    ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
    geW91IHNlZSBpdD8gIC0tIEp1ZXJk