in reply to Trying to re-use code at different levels of an inherited object.

Hi, this is what I got to work:

package Foo; # must use '\' to create the reference, and since it's a # reference not an invocation, we can't specify arguments # here. (see the .pl file at the end) *do_something = \&make_do_something; sub make_do_something { # make_do_something is the method called, hence the # object reference will be on *this* @_, not the # one below. my ($self, $name) = @_;
Update: I didn't quite get this, you do in fact have to grab the object reference here in the anonymous sub definition, which requires that the calling code in the script be $b->$sub(). When I realized this I went back and found the same problem that you've been having, and it sounds like chromatic has pointed out the grim reality of the situation. To avoid the compile-time check you could use 'SUPER' as a string in an eval block.
return sub { if ( $name ne 'foo' ) { print "Not foo\n"; $self->SUPER::do_something(); } print "Foo $name!!!\n"; return 1; } } 1; #File: Bar.pm package Bar; use base 'Foo'; *do_something = \&Foo::make_do_something; sub new { bless {}, shift(); } 1; #!/usr/local/bin/perl use lib '.'; use Foo; use Bar; $b = new Bar(); # just calling do_something won't cause the subroutine # returned to execute; we've got to do that ourselves. my $sub = $b->do_something('foo'); # supply args here, not above. stor +e the subroutine ref $sub->(); # dereference it to run it

Replies are listed 'Best First'.
Re: Re: Trying to re-use code at different levels of an inherited object.
by ehdonhon (Curate) on Jan 29, 2002 at 07:29 UTC

    If I understand you correctly, then I believe there are two problems with this,

    1. This requires that the coder using my object knows about the internal details of my object, and that the coder always knows at run time exactly what kind of object they have. I want them to be able to do_something with any subclass of Foo without having to know which subclass it is.
    2. I couldn't get your to work for me to work in all cases. When I modify the definition of $sub in the main package to call $b->do_something('bar'), I get the exact same error:
    Not foo
    Can't locate object method "do_something" via package "Foo"
     (perhaps you forgot to load "Foo"?) at ./foobar.pl line 20.