http://qs321.pair.com?node_id=836557


in reply to Re: Simple inheritance question
in thread Simple inheritance question

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.

Replies are listed 'Best First'.
Re^3: Simple inheritance question
by webfiend (Vicar) on Apr 23, 2010 at 16:38 UTC
    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.
        Basically, I have two classes that share a bunch of such internal functions (no object required, it's just string parsing)

        Put the functions into a third, non-class module, export them, and use it in both your class modules.

        Inheritance only works for methods, not plain ol' functions. And inheriting from a class that you've no intention of using inheritance--just so you can import some functions that live in the same file--leaves you open to all kinds of nasty surprises down the line.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        as if it were a function internal to Two, not requiring an object.

        As if it's something it isn't. So make it what you want it to be.

        BEGIN { *Two::test = \&One::test; }

        It's really weird to export functions from a Class module, though.

        Glad you got the solution you needed. I was a little unclear on the original question. I also think it's interesting that One doesn't need a constructor in the object solution. It makes sense, considering that a One is never instantiated. I didn't realize that Perl's package handling let's you "inherit" from a package that isn't actually a class.

        We learn something every day if we give ourselves a chance.