in reply to Re^3: my $self is stumped!
in thread my $self is stumped!

I agree that it's a big no-no to require the parent to have any knowledge of the child and that you shouldn't have to replicate functionality. But I also think that you brought the shenanigans on yourself by not maintaining a clear distinction between classes and instances (at least in the provided sample code; this problem may be an artifact of the sample rather than something present in your real project) - not all (non-child) people are named Alice, so that name should not be hardcoded in the class. Nor are all children named Billy the Kid. A child and its mother are two distinct people, therefore they should be instantiated as two distinct objects and one should refer to the other rather than trying to roll both into a single object.

Here's a slightly modified version of your original code which doesn't require either class to have any information about the internals of the other, doesn't replicate functionality from one class in the other, doesn't require any shenanigans, and maintains a clear distinction between classes and instances. I've also added in Billy's father to clarify that Alice (the instance) is distinct from person (the class). And Billy introduces himself twice, once via person's tellName and once via child's tellName, to show how to force the parent class's methods to call each other while maintaining encapsulation and avoiding duplicate code.

#!/usr/bin/perl use strict; package person; sub new { my $class = shift(@_); #my $self = { 'name' => 'Alice' }; my $self = { 'name' => shift }; 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(); person::tellName($self); } 1; package child; our @ISA = qw(person); # inherits from person sub new { my $class = shift(@_); #my $self = $class->SUPER::new(); my $self = $class->SUPER::new(shift); #$self ->{'nickName'} = 'Billy The Kid'; $self ->{'nickName'} = shift; $self->{mom} = shift; $self->{dad} = shift; bless $self, $class; return $self; } sub tellName { my($self)=$_[0]; print "$self->{'nickName'}.\n"; } sub introduce { #my($self)=$_[0]; print "Hi, I'm "; my($self)=$_[0]; $self->SUPER::introduce(); print 'but they also call me '; $self->tellName; print "Here's my mom: "; #$self->SUPER::introduce(); $self->{mom}->introduce; print "Here's my dad: "; $self->{dad}->introduce; } 1; package main; my $mom = new person('Alice'); my $dad = person->new('Charlie'); $mom->introduce(); # that time it works. $dad->introduce; print "\n"; my $son = new child('Billy', 'Billy the Kid', $mom, $dad); $son->introduce();

It produces the output:

Hello, I'm Alice. Hello, I'm Charlie. Hello, I'm Billy. but they also call me Billy the Kid. Here's my mom: Hello, I'm Alice. Here's my dad: Hello, I'm Charlie.