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

While I have been using the OOP interface of many modules
(even wrote some simple OOP Modules myself) I have ignored
inheritance up to recently.

After reading the inheritance examples in the perldocs I thought
it would be a nice idea to test my new knowledge on the local
web project I am working on. After restructuring some things
I have finally come up with something like this.
file - Project\Client.pm package Project::Client; use strict; sub new { my ($class, %args) = shift; $class = ref ($class) || $class; my $self = {}; ... bless ($self, $class); return $self; } ... file - Project\Client\Mode.pm package Project::Client::Mode; @ISA = ('Project::Client'); use strict; ... file - Project\Client\Mode\TestMode.pm package Project::Client::Mode::TestMode; @ISA = ('Project::Client::Mode'); use strict; ...
Now I expect the following to work.
file - client.pl use strict; use lib '...'; my $mode = Project::Client::Mode::TestMode -> new (...); ...
But I get the dreaded 'Can't locate object method "new" via package "Project::Client::Mode::TestMode"'
message. What am I doing wrong?

Replies are listed 'Best First'.
•Re: Inheritance not working
by merlyn (Sage) on Mar 23, 2002 at 15:58 UTC
Re: Inheritance not working
by mattriff (Chaplain) on Mar 23, 2002 at 15:51 UTC
    You need to "require" the modules that you are inheriting from.

    In Project::Client::Mode::TestMode you need:

    require Project::Client::Mode;

    And, in Project::Client::Mode you need:

    require Project::Client;

    That should take care of the error.

    - Matt Riffle

Re: Inheritance not working
by Kanji (Parson) on Mar 23, 2002 at 15:52 UTC

    You need to require or use the modules you're inheriting from, so that Perl has access to it's code.

    package Project::Client::Mode; require Project::Client; # <--- @ISA = ('Project::Client'); use strict; ...

    You might also want to check out the Inheritance section of perltoot, and base (which will combine the require and @ISA-population for you in one easy step).

        --k.


Re: Inheritance not working
by jepri (Parson) on Mar 23, 2002 at 16:38 UTC
    You also need to use  our @ISA=etc. . If you move the use strict up one line you will see what I mean :)

    ____________________
    Jeremy
    I didn't believe in evil until I dated it.

      Post hoc, ergo propter hoc.

      If he's not running under strict yet, any non-lexical variable declared will be autovivified as a package global. If he does swap the two lines, he will have to use our or vars, but that's because strict catches that sort of thing, not because it's necessary for inheritance purposes.

Re: Inheritance not working
by dreadpiratepeter (Priest) on Mar 23, 2002 at 15:53 UTC
    You need to:
    use Project::Client::Node::TestNode;
    in client.pl, or else the new subroutine never hits the symbol table. Perl will not go out and find packages just because you try to use a method in them. You must explicitly load them.
    UPDATE: I missed the requires in the parent classes. I tend to use use base, which does the requires automatically.
    Hope this helps.

    -pete
    "I am Jack's utter lack of disbelief"
Re: Inheritance not working
by trs80 (Priest) on Mar 23, 2002 at 19:45 UTC
    I struggled with this when first doing OOP and I agree with merlyn, using
    use base qw( Project::Client );
    style inheritance has proven the best solution for what I have needed.
    It removes the need to mess with ISA and/or require the module. It makes easy things easy :)