in reply to Detecting which class a method is defined in

If you don't mind delving into a bit of dark magic, B can come to your rescue here:
#!perl -l package A; sub foo { "A::foo" } sub bar { 'A::bar' } package C; @ISA = 'A'; sub bar { 'bar' } package main; use B 'svref_2object'; $x = bless {}, 'C'; for (qw(foo bar)) { print "$_ is from ", svref_2object(UNIVERSAL::can($x, $_))->GV->ST +ASH->NAME; }

Replies are listed 'Best First'.
Re^2: Detecting which class a method is defined in
by chromatic (Archbishop) on May 05, 2011 at 20:55 UTC

    The stash name is the name of the current package in which perl compiled the method. It can be wrong in cases where a method in a class comes from elsewhere, such as a role or a mixin.

      No, this is all compiled in main:
      #!perl -l $y='main';$A::y='A';$C::y='C'; sub A::foo { $y } sub A::bar { $y } @C::ISA = 'A'; sub C::bar { $y } use B 'svref_2object'; $x = bless {}, 'C'; for (qw(foo bar)) { print "$_ -> ", $x->$_, " from ", svref_2object(UNIVERSAL::can($x, + $_))->GV->STASH->NAME; }
      I guess the role and mixin stuff on CPAN must do something else if it breaks this.

        I mean this behavior:

        #!/usr/bin/perl -l $y='main';$A::y='A';$C::y='C'; package main; sub foo { $y } sub bar { $y } package A; *foo = \&main::foo; *bar = \&main::bar; package C; @C::ISA = 'A'; *bar = \&main::bar; package main; use B 'svref_2object'; my $x = bless {}, 'C'; for (qw(foo bar)) { print "$_ -> ", $x->$_, " from ", svref_2object(UNIVERSAL::can($x, + $_))->GV->STASH->NAME; }

        If you know the name of the intended destination stash at the time of writing the code, your example works fine. It's not always possible to know that, unfortunately.