in reply to Re: SUPER in OOPerl is dumped with $self
in thread SUPER in OOPerl is dumped with $self

Hi Monks,

The code in question was there at node my $self is stumped!. I am pasing the code below for your reference.

How do I get the parent method to call the parent second method? #!/usr/bin/perl use strict; package person; sub new { my $class = shift(@_); my $self = { 'name' => 'Alice' }; bless($self, $class); return($self); } sub tellName { my($self)=$_[0]; print "$self->{'name'}.\n"; } sub introduce { my($self)=$_[0]; print "Hello, I'm "; $self->tellName(); } 1; package child; our @ISA = qw(person); # inherits from person sub new { my $class = shift(@_); my $self = $class->SUPER::new(); $self ->{'nickName'} = 'Billy The Kid'; bless $self, $class; return $self; } sub tellName { my($self)=$_[0]; print "$self->{'nickName'}.\n"; } sub introduce { my($self)=$_[0]; print "Hi, I'm "; $self->tellName(); print "Here's my mom: "; $self->SUPER::introduce(); } 1; package main; my $mom = new person(); $mom->introduce(); # that time it works. print "\n"; my $son = new child(); $son->introduce();

When the child calls the parent method with $self->Super::firstmethod(), the parent method uses $self->secondmethod(). But the secondmethod() that gets called is the over-ride version, because $self is a reference to to the child object.

Replies are listed 'Best First'.
Re^3: SUPER in OOPerl is dumped with $self
by pajout (Curate) on Jul 03, 2007 at 10:47 UTC
    Consider situation, when you create $mom1, $mom2, $son1 and $son2 in your main package. That sons cannot know anything about their parent objects without explicit setting this relation. According to OO conception, they inherit from classes, not from objects (instantiated classes).

    My opinion is that it is not possible in your example, but you require something not compliant with OO.

    I see only this way:

    sub parent { my($self, $parent) = @_; $$self{parent} = $parent if defined $parent; return $$self{parent} }
    Update: Or, to allow unsetting of parent:
    sub parent { my($self, $parent) = @_; $$self{parent} = $parent if 1 < @_; return $$self{parent} }

      How can we work around when we have multiple inheritance?

      Update

      To be specific, the topic of discussion is how to workaround with SUPER so that Child will know who is the parent. On node "Re^3: SUPER in OOPerl is dumped with $self" monk pajout suggest some code to workaround with it. When there is multiple inheritence, its obvious that there are more than one parents and SUPER will be searching in @ISA. So question is, how the child will know who all are the parent(objects). How can I modify the solutions at "Re^3: SUPER in OOPerl is dumped with $self" to make the child, who all are its parent(objects)

        Yes, you are right. We cannot use SUPER as a reference to the instance of parent class, because it references parent class. There is no instance of parent class related with $self implicitly.

        Yes, Java is different from our perspective.

        How to handle multiple inheritance... To be open, I never had to do it. Anyway, do you mean class-inheritance or instance-inheritance?

        Multiple inheritance is implemented in Perl by placing all the base classes into the derived class's @ISA. If an instance of the derived class receives a call to a method the derived class doesn't define, the classes listed in @ISA are searched in order from left to right.

        e.g., Given the class Chimera where @Chimera::ISA = qw(Lion Snake Eagle), calling $my_chimera->speak will look first for Chimera::speak, then Lion::speak, then Snake::speak, and finally Eagle::speak and execute whichever it finds first.

        An object representing a child may or may not have objects representing its parents, but this has absolutely nothing to do with inheritance (multiple or otherwise) in the OO sense. As I said earlier, the different meanings of "parent" and "child" in the real-world context vs. the OO context appear to be confusing the issue here.

        Consider the following object model:

        Person --- Person::Child \-- Person::Adult
        Each Person::Child instance has an @parents property which holds one or more Person::Adult objects representing its parents (in the real-world sense), yet Person::Adult is not Person::Child's parent (in the OO sense).

        This example also answers the question of how to modify pajout's code to allow the child object to have an arbitrary number of parent objects (change the parent property to an array):

        sub parents { my $self = shift; push @{$self->{parents}}, @_ if @_; return @{$self->{parents}}; }
        ...but this is completely unrelated to multiple inheritance, so I question whether it's likely to tell you what you're actually trying to get at.
Re^3: SUPER in OOPerl is dumped with $self
by dsheroh (Monsignor) on Jul 03, 2007 at 16:24 UTC
    But the secondmethod() that gets called is the over-ride version, because $self is a reference to to the child object.

    Which is exactly as it should be - that's the nature of polymorphism.

    This isn't anything unique to Perl. Shortly after reading the original thread, I talked to a friend who's a Java programmer. He's been writing Java more-or-less exclusively for as long as I've known him (we met in 1999) and never touched Perl in his life. When I told him about the original post and that child::tellName was called instead of person::tellName, his exact reply was, "And that surprised him?"

    If you want to ignore polymorphism and have person::introduce always call person::tellName instead of any overridden version, then change the call in person::tellName from $self->tellName(); (which calls any overrides which may be in place for $self's class) to person::tellName($self); (which always calls person's version regardless of $self's class). I've already posted a revised version of the sample code which demonstrates this in the other thread at Re^4: my $self is stumped!.