use strict; use warnings; use Data::Dump qw/pp dd/; package FOO { sub foo { warn __PACKAGE__."::foo";}; sub bar { warn __PACKAGE__."::bar";} sub baz { warn __PACKAGE__."::baz";} }; package BAR { our @ISA = qw/FOO/; sub bar { warn __PACKAGE__."::bar";} sub can { my ( $self,$sym ) = @_ ; warn "Calling can in ".__PACKAGE__." for ".Data::Dump::pp $self; FOO->can($sym); } }; package BAZ { our @ISA = qw/BAR/; sub baz { warn __PACKAGE__."::baz";} sub can { my ( $self,$sym ) = @_ ; warn "Calling can in ".__PACKAGE__." for ".Data::Dump::pp $self; BAR->can($sym); } sub new { my ( $self,@args ) = @_ ; bless {@args} , __PACKAGE__; } }; package main; use Test::More; my $obj = BAZ->new(name=>"OBJ"); for my $sym (qw/foo bar baz/) { diag "****** Trying can($sym)"; diag "... as ->meth\n"; my $meth = $obj->can($sym); $obj->$meth() if $meth; diag "... as sub()\n"; my $sub = UNIVERSAL::can($obj,$sym); $obj->$sub() if $sub; is($meth,$sub,"same for $sym"); } done_testing; #### -*- mode: compilation; default-directory: "d:/tmp/pm/" -*- Compilation started at Sun Oct 10 20:52:31 C:/Strawberry/perl/bin\perl.exe -w d:/tmp/pm/tst_can.pl # ****** Trying can(foo) # ... as ->meth Calling can in BAZ for bless({ name => "OBJ" }, "BAZ") at d:/tmp/pm/tst_can.pl line 36. Calling can in BAR for "BAR" at d:/tmp/pm/tst_can.pl line 22. FOO::foo at d:/tmp/pm/tst_can.pl line 8. # ... as sub() FOO::foo at d:/tmp/pm/tst_can.pl line 8. ok 1 - same for foo # ****** Trying can(bar) # ... as ->meth Calling can in BAZ for bless({ name => "OBJ" }, "BAZ") at d:/tmp/pm/tst_can.pl line 36. Calling can in BAR for "BAR" at d:/tmp/pm/tst_can.pl line 22. FOO::bar at d:/tmp/pm/tst_can.pl line 9. # ... as sub() BAR::bar at d:/tmp/pm/tst_can.pl line 18. not ok 2 - same for bar # Failed test 'same for bar' # at d:/tmp/pm/tst_can.pl line 67. # got: 'CODE(0x6c5730)' # expected: 'CODE(0x67f920)' # ****** Trying can(baz) # ... as ->meth Calling can in BAZ for bless({ name => "OBJ" }, "BAZ") at d:/tmp/pm/tst_can.pl line 36. Calling can in BAR for "BAR" at d:/tmp/pm/tst_can.pl line 22. FOO::baz at d:/tmp/pm/tst_can.pl line 10. # ... as sub() BAZ::baz at d:/tmp/pm/tst_can.pl line 32. not ok 3 - same for baz # Failed test 'same for baz' # at d:/tmp/pm/tst_can.pl line 67. # got: 'CODE(0x6c57d8)' # expected: 'CODE(0x26cbc28)' 1..3 # Looks like you failed 2 tests of 3. Compilation exited abnormally with code 2 at Sun Oct 10 20:52:32