Search code examples
perlclassinheritancesubclassexporter

How can I share variables between a base class and subclass in Perl?


I have a base class like this:

package MyClass;

use vars qw/$ME list of vars/;
use Exporter;
@ISA = qw/Exporter/;
@EXPORT_OK = qw/ many variables & functions/;
%EXPORT_TAGS = (all => \@EXPORT_OK );

sub my_method {

}
sub other_methods etc {

}

--- more code---

I want to subclass MyClass, but only for one method.

package MySubclass;

use MyClass;
use vars qw/@ISA/;
@ISA = 'MyClass';

sub my_method {

--- new method

}

And I want to call this MySubclass like I would the original MyClass, and still have access to all of the variables and functions from Exporter. However I am having problems getting the Exporter variables from the original class, MyClass, to export correctly. Do I need to run Exporter again inside the subclass? That seems redundant and unclear.

Example file:

#!/usr/bin/perl

use MySubclass qw/$ME/;

-- rest of code

But I get compile errors when I try to import the $ME variable. Any suggestions?


Solution

  • You're not actually inheriting MySubclass from MyClass at all -- MySubClass is a user of MyClass. What you're doing is overriding a bit of behaviour from MyClass, but you will only confuse yourself if you think of this as inheritance, because it isn't (for example: where is your constructor?) I couldn't figure out what you were trying to do until I ignored everything the code was doing and just read your description of what you want to have happen.

    Okay, so you have a class which imports some symbols - some functions, and some variables:

    package MyClass;
    use strict;
    use warnings;
    
    use Exporter 'import';    # gives you Exporter's import() method directly
    our @EXPORT_OK = qw/ many variables & functions/;
    our %EXPORT_TAGS = (all => \@EXPORT_OK );
    our ($ME, $list, $of, $vars);
    
    sub my_func {
    
    }
    sub other_func {
    
    }
    1;
    

    and then you come along and write a class which imports everything from MyClass, imports it all back out again, but swaps out one function for another one:

    package MyBetterclass;
    use strict;
    use warnings;
    use Exporter 'import';    # gives you Exporter's import() method directly
    our @EXPORT_OK = qw/ many variables & functions /;
    our %EXPORT_TAGS = (all => \@EXPORT_OK );
    use MyClass ':all';
    
    sub my_func {
        # new definition   
    }
    1;
    

    That's it! Note that I enabled strict checking and warnings, and changed the names of the "methods" that are actually functions. Additionally, I did not use use vars (the documentation says it's obsolete, so that's a big red flag if you still want to use it without understanding its mechanics).