http://www.perlmonks.org?node_id=836554


in reply to Simple inheritance question

The main problem here is that you don't have a constructor for package One, so there's nothing for package Two to inherit. There are a lot of other little things with the code (like the fact that test() is a simple sub rather than a method, for example) which suggest the Perl OO tutorial perltoot might be a good item for you to read for a handle on how objects are handled in Perl.

Edit: I answered the wrong question and with an inaccurate answer. Then again, I learned something new about Perl and how it handles inheritance, so it wasn't a total loss.

Replies are listed 'Best First'.
Re^2: Simple inheritance question
by halfcountplus (Hermit) on Apr 23, 2010 at 16:26 UTC
    Adding a constructor to One does not make any difference. Would have been nice if you could have named those "little things" since I have already read the man page, and all of "Intermediate Perl" (the OO book).

    AFAICT it simply isn't possible to call a method from One in Two without using a class prefix. Simple confirmation of this (from someone who knows) will suffice, using One::test() instead of test() is fine, it just seems slightly silly, since One inherited Two's methods.
      Would have been nice if you could have named those "little things"

      That's a fair point. Here's a modified version of the code doing what I think you might have been trying to do. I'm also realizing I may have misread the question, but I've got momentum now. Might as well paste what I have.

      #!/usr/bin/perl # Use the warnings pragma rather than the -w flag use warnings; use strict; { package One; # Define a constructor for One sub new { my $class = shift; # Constructors need to know what class they +'re for my $self = {}; bless($self, $class); # Tell Perl what $self is being blessed +into } sub test { my $self = shift; # Is this an object method? Better grab $sel +f my $x = pop @_; # I usually shift from the argument list, but +whatever # Also, I like to be explicit about what I'm # popping/shifting from print "$x\n"; } } { package Two; use base "One"; # Two::new didn't add anything to One, so I removed it. sub eg { my $self = shift; # Is this an object method? Better grab $se +lf my $arg = pop @_; # pop() again? Okay, break it out and make +it explicit. $self->test($arg); # Is test() an object method? I'll use it a +s if it was. } } my $obj = new Two(); $obj->eg("hello");

      Edit: Incidentally, I think jethro has the solution you're looking for. I've become so used to making everything explicit by spelling out object or module connections that I didn't even think of Exporter.

        Yeah, $self->test will work (altho this still does not require a constructor for One, seems like a red herring):
        #!/usr/bin/perl -w use strict; { package One; sub test { my $x = pop; print "$x\n"; } } { package Two; use base "One"; sub new { my $self = {}; bless($self); } sub eg { my $self = shift; $self->test(pop); } } my $obj = new Two(); $obj->eg("hello");
        I guess this is starting to seem a little finnicky, but I would like to use test() as if it were a function internal to Two, not requiring an object.

        Basically, I have two classes that share a bunch of such internal functions (no object required, it's just string parsing), so I thought the best thing would be to have a base class containing those.

        In fact Exporter does work, see my reply to jethro.