in reply to Re: Instance field access from private methods
in thread Instance field access from private methods

I'm not too sure. I wrote this (first time messing w/ iheritence w/ perl), and C2 obviously inherited the method printWorld even though printWorld isn't passed the invocant of printGoodBye.

C1.pm:
*******
package C1; sub new { my $class = shift; my $self = {}; return bless $self, $class; } sub printGoodBye{ print "Goodbye @_ "; printWorld(); } sub printWorld{ print "World\n @_"; } 1; END {}

C2.pm
******
package C2; use base ("C1"); sub new { my $class = shift; my $self = {}; return bless $self, $class; } sub printHi{ print "Hi\n"; } 1; END {}

o.pl
****
#!/usr/bin/perl use C2; $bob = C2->new(); $bob->printGoodBye(); exit 0;


Let me know if I'm wrong, but this sure looks like it's inheriting something w/o $self being passed to me. Mark

Replies are listed 'Best First'.
Re: Re: Re: Instance field access from private methods
by guha (Priest) on Oct 23, 2002 at 19:42 UTC

    Let me know if I'm wrong, but this sure looks like it's inheriting something w/o $self being passed to me.

    But it *is* passed, actually $bob is passed as the first element of @_ which is seen in the output

    Goodbye C2=HASH(0x177f054) World

    So you would normally shift off the first element to a lexical variable often called $self to use the subroutine as a method in OO-style

    sub printGoodBye { my $self = shift; print "Goodbye "; $self->printWorld(); } sub printWorld{ my $self = shift; print "World\n "; }

    So inheritance is really in play here.
    I am also a newbie when it comes to perl-OO, so I watch this thread with keen interest.(++)

      I think you have shown me what I'm doing wrong here. Inside of your printGoodBye method, you call printWorld() w/ $self as the invocant whereas I had always been calling that method without any invocant at all. Heh, java rears it's ugly head :)

      This must be what robartes meant when he wrote: "...it is a good idea that even your private methods use the class' public accessor methods to get at private instance attributes."

      Excellent, excellent.

      Now, I'm still not too sure about a subroutine being required to recieve a copy of the invocant in order for it to be classified as a method and thus inheritable. You are right that printGoodBye() recieves the invocant, but printWorld() does not (or else there would be a HASH=... after "World" in the output). However, printWorld is still inherited from C1 by C2.

      So, chances are, I'm thinking about this in java-world and being stupid again. But, my original question has been answered, so thanks, guha.



      Mark
        The reason printWorld is not printing "HASH=" is that you are calling it incorrectly. You're invoking it as a subroutine, not as a method, so it is not inherited at all; it just happens to be in the same package as printGoodBye.

        The correct way to call it is to use the version of printGoodBye in guha's post, which uses $self->printWorld() instead.

        Well I think the thing is that you invoke printGoodBye as subroutine with no argument, so in your example nothing should be printed

        If you would for some reason put

        printGoodBye(@_); # instead
        you would see the HASH-stuff

        However I think that in order for inheritance to work, the "hash" or instance or ... needs to be BLESSED to some package

        The reason it *seems* to work is that printWorld and printGoodBye are defined in the same package.