TorontoJim has asked for the wisdom of the Perl Monks concerning the following question:

This is the first time I've tried writing a child class to a parent class. I've been googling and PerlMonk'ing for days and I'm still missing something that is obviously important.

I want to have a perl script where I call MyParent and MyParent::MyChild. Then in the code, create the object for MyParent and access the methods in MyParent::MyChild.

This is the MyParent class (MyParent.pm):

package MyParent; use strict; no strict "refs"; use Carp qw(carp croak); our $VERSION = .01; sub new { my $class = shift; bless { something => "foo", }, $class; return $self; } sub parent_nifty_method1 { print $_[0]->{something}; } sub parent_nifty_method2 { ... pah ... }

Then comes the child class MyParent::MyChild (MyChild.pm):

package MyParent::MyChild; use strict; no strict "refs"; use Carp qw(carp croak); use parent qw(MyParent); our @ISA = qw(MyParent); our @EXPORT = qw( method_a method_b ); my $VERSION = .01; sub new { my $class = shift; my $this = bless {}, $class; my( $parent ) = @_; $this->{PARENT} = $parent; return $this; } sub child_method_a { #read parent variable, not change it print MyParent->{something}; } sub child_method_b { ... incredibly cool stuff ... }

Now comes the Perl script running on the web server and what I would LIKE to do, but can't make it work, probably because I don't drink enough coffee.

script_to_change_the_world.pl #!/usr/bin/perl use MyParent; use MyParent::MyChild; use strict; my $parentobject = MyParent->new(); $parentobject->method1; #prints: Foo #Now I want to access something or other in the MyChild, doing it this + way (which is what inheritance means to me) $parentobject->child_method_a; #Prints: Foo

However, the problem is that when I do this, I get this error:

Can't locate object method "child_method_a" via package "MyParent" at +script_to_change_the_world.pl line 14.

I think I've tried to do TOO much in setting these up properly and I'm missing the variables for the methods (to use a metaphor).

Can some kind Monk please clarify what I'm doing wrong above?

Thanking you for your kindness and time.

Replies are listed 'Best First'.
Re: Parent cannot call Child method
by Eily (Monsignor) on Mar 17, 2016 at 12:42 UTC

    It actually works the other way around. An object of the class MyParent::MyChild will be able to call methods defined in the parent, if the child does not have a method of the same name itself. So you want to try my $obj = MyParent::MyChild->new(); $obj->parent_nifty_method1();

    use parent qw(Parent); already sets the @ISA of the child (and it pushes the parent in the @ISA instead of replacing it, so that a class may inherit from more than one), so you don't have to do it afterwards.

      Thank you.

      I tried it that way and got this error:

      Can't locate object method "new" via package "MyParent::MyChild" (perh +aps you forgot to load "MyParent::MyChild"?) at

      This is how I changed the original call:

      use MyParent::MyChild; my $obj = MyParent::MyChild->new(); $obj->parent_nifty_method1;

      I tried use MyParent in addition to use MyParent::MyChild, neither worked.

        Did you, as Eily suggested, use parent qw(Parent); in MyParent::MyChild?
Re: Parent cannot call Child method
by perlfan (Parson) on Mar 17, 2016 at 15:09 UTC
    You need to use SUPER. See perlobj. However, You're doing it wrong by putting a reference to parent in the child object. The whole point of inheritance is to make the parent's methods available to the child. See the second example.

    Example 1: Your current code fixed up (as a monolithic file):

    ackage MyParent; use strict; use Carp qw(carp croak); our $VERSION = .01; sub new { my $class = shift; my $self = bless { something => "foo", }, $class; return $self; } sub parent_nifty_method1 { my $self = shift; print $self->{something}; } sub parent_nifty_method2 { my $self = shift; #... pah ... } package MyParent::MyChild; use strict; use base qw(MyParent); our $VERSION = .01; sub new { my $class = shift; my $parent = $class->SUPER::new; my $self = bless { PARENT => $parent, }, $class; return $self; } sub child_method_a { my $self = shift; #read parent variable, not change it print $self->{PARENT}->{something}; } sub child_method_b { my $self = shift; #... incredibly cool stuff ... } package main; #use MyParent; #use MyParent::MyChild; #use strict; my $parentobject = MyParent->new(); $parentobject->parent_nifty_method1; #prints: foo #Now I want to access something or other in the MyChild, doing it this + way (which is what inheritance means to me) my $childobject = MyParent::MyChild->new; $childobject->child_method_a; #Prints: foo 1;

    Example 2 - redefined MyParent::MyChild that actually inherits MyParent and builds on it:

    package MyParent::MyChild; use strict; use base qw(MyParent); our $VERSION = .01; sub new { my $class = shift; my $parent = $class->SUPER::new; # extend blessed reference $parent with a new field $parent->{another_something} = "bar"; my $self = bless $parent, $class; return $self; } sub child_method_a { my $self = shift; #read parent variable, not change it $self->parent_nifty_method1; } sub child_method_b { my $self = shift; print $self->{another_something}; } package main; #use MyParent; #use MyParent::MyChild; #use strict; my $parentobject = MyParent->new(); $parentobject->parent_nifty_method1; #prints: foo #Now I want to access something or other in the MyChild, doing it this + way (which is what inheritance means to me) my $childobject = MyParent::MyChild->new; $childobject->child_method_a; #Prints: foo $childobject->parent_nifty_method1; #Prints: foo $childobject->child_method_b; #Prints: bar
      As it turns out, it was not a problem with how I was "creating" the modules and the parent/child relationship. The problem was my understanding of inheritance.

      After some more reading, I went back and rewrote them. I had originally written one big module and tried to then make smaller children from it.

      As my ex would attest, I have a problem making children.

      Now that I have changed my expectation and no longer expect this parent/child structure to work like one big module, everything started falling into place.

      Thank you all for your help in getting me here.