You are trying to "inherit", with use parent
, in a module from a module. The parent says
Establish an ISA relationship with base classes at compile time
(my emphasis). It is a pragma to set up use of a base class in a derived one, and Internal
and Internal::Utility
are not classes really (they don't bless
).† See a note at the end.
Write them as classes. (Then you won't need to think about exporting symbols.) That will give you a whole lot more capability and control, too.
As for the Exporter
, you have to say
use Exporter 'import';
so that the sub import
is available to the module.
A sub named "import" is used to push symbols, that you specify in @EXPORT_OK
etc, to the caller and thus must exist in a module. Or, quite nicely, a module may "borrow" it from Exporter
, instead of implementing its own. But the Exporter
doesn't export it by default.
An example with classes, showing a few ways to make constants available, along with a few other bits. When you choose one way (and remove code for others) and remove prints it gets far simpler; the longest Internal::Utility
class shrinks to a few lines.
Base class Internal.pm
package Internal;
use warnings;
use strict;
# Set up constants for derived classes to use, for demo
# BOTH via class data and method, and via an attribute
our $NOW = time;
sub get_NOW { return $NOW }
sub new {
my ($class, @pars) = @_;
# Set up object's data ("attributes"), using @pars
my $self = { _now => $NOW }; # ...
# Make $self an object and this package a class
return bless $self, $class;
}
sub other_methods { }
1;
Derived class (subclass), Internal/Utility.pm
package Internal::Utility;
use warnings;
use strict;
use feature 'say';
use parent 'Internal'; # now have everything from 'Internal' class
# Retrieve constant from parent, if you *must*
# It is much better to use a method or an attribute
use mro;
my $NOW = do {
my $Parent = (__PACKAGE__)->mro::get_linear_isa->[1];
my $now = $Parent . '::NOW';
no strict 'refs';
$$now;
};
my $Now = $Internal::NOW; # or use hard-coded parent name
# Constructor is also inherited (can change or override it altogether)
sub print_start_time {
my $self = $_[0];
say "\tIn ", __PACKAGE__, ". Start time:";
say "\tObject's method (inherited): ", $self->get_NOW;
say "\tObject's data (inherited): ", $self->{_now};
say "\tDirectly, as class method: ", Internal->get_NOW;
say "\tClass variable, from parent: $NOW";
say "\tOther class variable: $Now";
};
1;
Driver main.pl
use warnings;
use strict;
use feature 'say';
use Internal::Utility;
my $obj = Internal::Utility->new();
say "Created ", ref $obj, " object";
$obj->print_start_time();
say "class constant: $Internal::NOW";
say "as object method: ", $obj->get_NOW;
say "as class method: ", Internal->get_NOW;
This prints
Created Internal::Utility object
In Internal::Utility. Start time:
Object's data (inherited): 1513229709
Object's method (inherited): 1513229709
Directly, as class method: 1513229709
Class variable, from parent: 1513229709
Other class variable: 1513229709
class constant: 1513229709
as object method: 1513229709
as class method: 1513229709
It is best to simply use the parent's attribute or its method, which are both inherited by its subclasses. If you use an attribute then provide an accessor for it in each subclass that uses it, for users of those subclasses.
There are differences between these two and which to choose depends on design details. As a basic I'd go with the method. Remember that the parent's class variables are accessible to any user of its derived classes.
Once you get to working with objects in Perl I recommend getting familiar with its native system. Then at some point one should look into Moose
and/or its light-weight sibling Moo
A note on class vs. object (instance) methods
A "class method" does not relate to any one object in particular, but rather to a class as a whole (say, return a number of objects created up to that point); thus it doesn't need an object's data. When a method is called on the class name it is the class name that is passed to it as the first argument and this is what makes it a "class" method.
An "object (instance) method" is meant to do work for a specific object, and when called on an object it is the object (reference to a Perl data structure used to store data in that class) that is passed to it.
Perhaps confusingly, we can call a method intended as a class method on an object as well, without errors (unless the method uses the class name which now it wouldn't have); this shouldn't be done as it muddies the purpose. Calling an instance-meant method with the class name would probably be bad, since it most likely does expect an object to be passed, while it will get a plain string with a class name.
This apparent ambiguity may be more confusing in this simple demo, as get_NOW
can be called equally well on a class and on an object. Its intent is clearly of a class method. But it can also be useful with an object, in inherited classes where methods don't have the parent's name.
A note on packages and classes
A package
Declares the BLOCK or the rest of the compilation unit as being in the given namespace.
Then you define sub
s in it and provide a way for those symbols (names) to be exported to the caller so that they can use them conveniently. You have a library of functions and that is that. This is mostly called a "module," which is how I used the term above. See more in perlmod.
A class is code/namespace (for the lack of a better noun for it) that can be instantiated, meaning that you can create an instance of it, an object. This object "knows" what class it is associated with so that it can use subs provided in that class, making them methods. The system provides a way for a class to set up data (attributes), and each object gets its own copy. See perlootut.
In Perl, a class is defined as (is) a package. What makes it a class, so that one can instantiate an object for it, is that a reference is bless-ed into it. Normally there is a subroutine in that package in which a reference (typically to a hash) is bless
-ed "into" the package (bless REF, PACKAGENAME
) and returned.† The perlobj says (my emphasis)
Objects are merely Perl data structures (hashes, arrays, scalars, filehandles, etc.) that have been explicitly associated with a particular class.
That object (the bless
-ed and returned hashref) has an OBJECT
flag in it (and a STASH
), on top of other properties that a hashref internally has. So when it is dereferenced the interpreter can tell that the sub should be sought in that package; thus this is an object of a class.
Thus the modules in this question are just not classes (in the usual sense†). Then what about "inheritance," a typical object-oriented term? Since Perl's OO system is minimalist some facilities apply to both generic modules and classes, and the terminology may get fuzzy here or there. The word "inheritance" is one such example as it may be used with its more generic meaning, where one unit picks up things setup in another.
I'd still advise to not use parent
pragma on modules which aren't classes, even as it works.
† A couple of semantic points, one brought up in a comment
Strictly speaking, a "class" is a package -- period. No need to have a bless
-ing subroutine in it. An "object" is an instance of a package, by the virtue of the package being bless
-ed into it. In a way, in Perl there are no special "class" and "object" things (even though those words are used) -- there are packages and their instances (associated with packages via bless
.)
All of this is clearly and precisely stated and discussed in the text but given a comment about it I'd like to clarify it further.
Taking the above dead-serious-formally pushes the Perl's intentionally minimalist OO-model too far, and further than intended, I believe. What is a purpose of calling a package a class if it doesn't produce an object (has no bless
-ing sub)? And am I going to pick any old reference in my code and bless
a package with it, as I can? Um, no. (If anyone would say 'yes' please provide an example from the wild, of a non-trivial example of a package without bless
that meaningfully acts as a class.)
A "class" (package) is normally written so to work for a particular reference involved with bless
-ing it, which has particular attributes, etc. Thus that reference and its bless
-ing generally belongs to that package, and practically this is what makes that package a class.
Well-- I note here that one can use bless
in far more flexible ways. For example, say bless $a_reference;
right in the (main::
) program and then that $a_reference
is associated with the package main::
, thus making that package its "class." Or see a rather involved example in this Effective Perler article.
The referent is bless
-ed, really. See, for instance the good old Bless My Referents