http://qs1969.pair.com?node_id=821583

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

Hi All,

It's been years since I posted here... I've been away with the fairies in Python and Ruby land for so long I've forgotten almost everything I ever knew about Perl OO...

I have no doubt that the following question is extremely basic..

I want to extend a class for a Perl API with one additional method.

I have the method but I don't want to edit the core API files. I would like to simply add the method in my script.

So, to test this: filename: SPEAK/ITALIAN.pm
package SPEAK::ITALIAN; use strict; use warnings; use Exporter; use vars qw(@ISA @EXPORT); @ISA = qw( Exporter ); @EXPORT = qw(hello); use constant HELLO => "Hello"; use constant GOODBYE => "Goodbye"; sub hello { print HELLO . " in Italiano\n"; } return 1;

Now, in my script (in this case "test.pl") I simply want to add a method to the SPEAK::ITALIAN class with all constants and other good stuff in the correct namespaces and so on

filename: test.pl
#!/usr/bin/perl use strict; use warnings; use SPEAK::ITALIAN; sub goodbye{ print GOODBYE . " in Italiano\n"; } hello(); goodbye();
Running this gives:
Hello in Italiano! GOODBYE in Italiano!

As you've noticed, GOODBYE is incorrect. It's not picking up the constant from the SPEAK::ITALIAN module.

I know I'm missing something very basic. Do I need "use base qw(SPEAK::ITALIAN)"?

Any pointers?

Thanks in advance and apologies for the awfulness of the question...

S

Replies are listed 'Best First'.
Re: Very basic package / module question...
by almut (Canon) on Feb 05, 2010 at 15:52 UTC

    If you want to make the constants available in the namespace that uses SPEAK::ITALIAN, you need to export them, just like you did with the sub hello:

    @EXPORT = qw(hello HELLO GOODBYE);

    Otherwise, you have to access them fully qualified:

    print SPEAK::ITALIAN::GOODBYE . " in Italiano\n";

    Update: or you could do it the OO way (via inheritance):

    package SPEAK::ITALIAN; use strict; use warnings; use constant HELLO => "Hello"; use constant GOODBYE => "Goodbye"; sub new { my $class = shift; return bless {}, $class; } sub hello { print HELLO . " in Italiano\n"; } 1; # the derived class (SPEAK/ITALIAN/Goodbye.pm) package SPEAK::ITALIAN::Goodbye; use strict; use warnings; use base "SPEAK::ITALIAN"; sub goodbye { my $self = shift; print $self->GOODBYE . " in Italiano\n"; } 1; # your script #!/usr/bin/perl use strict; use warnings; use SPEAK::ITALIAN::Goodbye; my $obj = SPEAK::ITALIAN::Goodbye->new(); $obj->hello(); $obj->goodbye();

      (about a year passes...)

      I ended up using inheritance...

      Thanks all!

      SM

Re: Very basic package / module question...
by CountZero (Bishop) on Feb 05, 2010 at 16:28 UTC
    Welcome back to Perl!

    Your problem is twofold:

    1. This module does not seem to be OO. It exports a function (hello) but not the constant GOODBYE;
    2. Your subroutine goodbye does not live in the SPEAK::ITALIAN package, so you could consider adding package SPEAK::ITALIAN; just bebfore your subroutine definition.
    As from that place in your program all functions, constants, variables, ... will be considered to reside in the SPEAK::ITALIAN package unless you fully qualify them, as almut already said.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: Very basic package / module question...
by rir (Vicar) on Feb 05, 2010 at 16:30 UTC
    Not very basic at all.

    You can put your goodbye into the ITALIAN namespace and import it by hand into your working namespace as shown below. This kind of stuff scales poorly.

    #!/usr/bin/perl use strict; use warnings; use SPEAK::ITALIAN; package SPEAK::ITALIAN; sub goodbye{ print GOODBYE . " in Italiano\n"; } package main; use vars "*goodbye"; *goodbye = \&SPEAK::ITALIAN::goodbye; hello(); goodbye(); __DATA__ Hello in Italiano Goodbye in Italiano
    Be well,
    rir
Re: Very basic package / module question...
by pileofrogs (Priest) on Feb 05, 2010 at 20:49 UTC

    ++

    I just want to say this is one of the most well written questions I've seen. Not only do you explain yourself well, you took your problem and boiled it down to some very small example code. I'm going to post a link to this every time someone asks an unclear question.

    (Now if only someone would help me write clearer questions...)

    --Pileofrogs

      Thankyou! Very kind...

      S