How can I exchange variables between base class and subclass in Perl?
I have a base class:
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 it MySubclass
as I would use the original MyClass
one and still have access to all the variables and functions from Exporter
. However, I am having trouble getting the correct variable values Exporter
from the original class MyClass
. Do I need to run again Exporter
inside a subclass? This seems overkill and obscure.
Example file:
#!/usr/bin/perl
use MySubclass qw/$ME/;
-- rest of code
But I am getting compilation errors when I try to import a variable $ME
. Any suggestions?
a source to share
You actually inherit MySubclass
from MyClass
- MySubclass
is user MyClass
. What you are doing is overriding a bit of behavior from MyClass
, but you would only get confused if you think of it as inheritance because it is not (ex: where is your constructor?) I couldn't figure out what you were trying to do until I ignored everything the code did and just read your description of what you want.
So, you have a class that imports some symbols - some functions and some variables:
package MyClass;
use strict;
use warnings;
use Exporter 'import'; # gives you Exporter 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 and write a class that imports everything from MyClass, imports it back again, but swaps one function for another:
package MyBetterclass;
use strict;
use warnings;
use Exporter 'import'; # gives you Exporter 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;
What is it! Note that I've included strict checks and warnings and changed the names of "methods" which are actually functions. Also, I haven't used it use vars
(the documentation says it's outdated, so it's a big red flag if you still want to use it without understanding its mechanics).
a source to share
You must have access to all methods. Forget about passing variables around.
You are getting a syntax error because you have a syntax error:
use MySubclass /$ME/; # syntax error - that the match operator
You need a list:
use MySubclass qw/$ME/;
However, don't do this. Access this data using methods. Since you are inheriting methods, you do not need (and should not use) the Exporter:
package MyClass;
BEGIN {
my $ME;
sub get_me { $ME }
sub set_me { $ME = shift }
}
Now your subclass is fair:
package MySubclass;
use parent( MyClass );
sub my_method { ... }
There are various modules that can automatically handle access details for you if you have many variables that you need to provide.
a source to share
In general, OO Perl and Exporter are usually kept separately rather than mixing them together. This is one of the reasons.
As Brian said, it will be much easier for you to get this to work in the first place and extend it further in the future if you take all the crap you export, turn it into class properties / methods, and get rid of the exporter entirely. The simple fact that the way you want to do this requires you to import and re-export everything should be a big, flashing prompt, which is probably the best way to do it (i.e. a way that is not related to the exporter).
a source to share
# use setters and getters the Perl way
#
# ---------------------------------------
# return a field value
# ---------------------------------------
sub get {
my $self = shift;
my $name = shift;
return $self->{ $name };
} #eof sub get
#
# ---------------------------------------
# set a field value
# ---------------------------------------
sub set {
my $self = shift;
my $name = shift;
my $value = shift;
$self->{ $name } = $value;
}
#eof sub set
#
# ---------------------------------------
# return the fields of this obj instance
# ---------------------------------------
sub dumpFields {
my $self = shift;
my $strFields = ();
foreach my $key ( keys %$self ) {
$strFields .= "$key = $self->{$key}\n";
}
return $strFields;
} #eof sub dumpFields
a source to share