Importing subroutines from parent class - perl

I am just a beginner with perl and trying to wrap my head around objects.
I am having no problem creating a object, however, I am having issues when I introduce a child class (sorry if wrong terminology) and exporting everything to the main:: script. When I say everything essentially I mean the subroutines (not methods) I want exported from the parent .pm. See code below.
#main.pl
use A::B;
my $string = format_date();
#A.pm
package A;
use strict;
use Exporter qw(import);
our #EXPORT = qw(format_date);
sub format_date { #do stuff}
#other subroutines/methods in package A
#B.pm -> located in A/B.pm
package A::B;
use strict;
use base qw(A);
other code in package B
I was expecting the 'use A::B;' syntax to load the format_date subroutine to the main:: script. When I run it I get - Undefined subroutine &main::format_date called at.....
When I use 'use A;' in main.pl everything runs fine.
What am I missing?
Note - some of our stations use 5.8.8 so some syntax needs to be slightly older, like the use base. Most use 5.34, but not all.

Subclasses inherit methods defined in parent classes, but don't automatically import subs from parent classes. (Inheritance is more a run-time feature, and importing is more a compile-time feature.)
Generally speaking, if you're trying to use object-oriented features to write a module (like using inheritance, defining methods, a constructor, a destructor, etc) and the module is also an exporter, then you probably want to step back to the design phase. Consider splitting it into two separate modules: an object-oriented one and a function exporter.
(It certainly is possible to write modules that do both, but in most cases, it's an sign that you've got a confused design.)

What am I missing?
In short: main.pl calls a subroutine (format_date) by its unqualified name that's never been imported to it. (Further, the program doesn't even load the package in which that sub is defined.)
The problem is that the question mixes up notions of class and package. While Perl allows us to do so as the distinction is blurry,† we don't have to abuse it: your packages A and A::B aren't much of a class -- they cannot construct an instance (an object) as there is no sub that bless's a referent, and they don't use other object-oriented tools either (the indicated inheritance isn't used).
Then treating them as a class hierarchy bites: that inheritance established in the question doesn't import subs, as explained by tobyink.
The simplest way to fix this is to make your packages into normal classes and use them as such.
The program (main.pl)
use warnings;
use strict;
use feature 'say';
use A::B;
my $obj = A::B->new;
my $string = $obj->format_date();
say $string;
File A.pm
package A;
use warnings;
use strict;
sub new { bless {}, shift } # make it a proper constructor...
sub format_date { return scalar localtime }
# other subroutines/methods in package A
1;
File A/B.pm
package A::B;
use warnings;
use strict;
use parent qw(A); # or, if you must: use base qw(A)
# other code in package B
1;
Now calling perl main.pl prints the (local) date, Wed Jan 18 13:56:47 2023.
Another way would be to have them as mere packages and to write A::B so that it (explicitly) imports needed subs from A, as they are requested. This is much more complicated and has no advantages over having classes.
See this SO page for more.
Alternatively, you could carry on the act and with the code you have actually treat A and A::B as classes, with A::B inheriting from A -- call format_date as a class method.
So instead of my $string = format_date(), use
my $string = A::B->format_date();
Now format_date is taken as a class method and since it is not defined in A::B the inheritance hierarchy is followed and it is found in A. The package name (A::B) is passed as the first argument and the method runs.
However, I wouldn't recommend this. Using packages both as classes and for exporting is complicated to get right, complex in use -- and there is no reason for it.
† A class is a package, firstly. See the reference perlobj and the tutorial perlootut.
For example, with an ordinary package, that never desired to be a class, we can call its subs as Packname->subname -- and it will behave as a class method, where Packname gets passed to subname as the first argument.
But this is more of a side-effect of Perl's (intentionally) simple object-oriented system, that shouldn't be abused. I strongly recommend to not mix: don't push an exporting package to be used as a class (perhaps by slapping an OO feature to it, like inheritance), and don't EXPORT from a class (a package intended for object-oriented use, that normally has a bless-ing sub(s)).
See the footnote, and the preceding text, in this post, for more elaborate statements on class-vs-package in Perl.

Related

When do Perl package variables fall out of scope?

From my main program I require a file containing a package, and then call a subroutine from that package:
while($somecondition){
require( 'people.pm' );
my $result = PERSON::stuff($args);
}
The PERSON package has multiple subs and some 'our' variables declared:
package PERSON;
our $name;
our ...
sub stuff {
...
}
In my understanding of other more object oriented languages you would need to declare a new object instance, maybe with its own constructor/initialization functions to use "package" variables. That doesn't seem to be the case here with Perl.
I'm dealing with legacy code so I don't want to change much, I just want to understand when the package variables ($name) come into existence, and when are they returned to memory from the perspective of the main program.
Would putting a PERSON::stuff() call after the while loop have new package variables?
After calling a single function inside a package do the package variables live until the end of the program?
The question mixes up some concepts so let's first address what appears to be the main issue: If a package is require'd inside some scope, what of it outside of that scope?
In short, (dynamical global) symbols from the package are accessible everywhere in the unit in which it is require'd, via their fully qualified names.†
Let's try with an example
use warnings;
use strict;
use feature 'say';
TEST_SCOPE: {
say "In scope, in ", __PACKAGE__;
require TestPack;
#hi(); # "Undefined subroutine &main::hi called..."
TestPack::hi(); # ok
#say $global; # $global ... who??
say $TestPack::global; # ok
say "Leaving scope\n";
};
say "--- in ", __PACKAGE__;
TestPack::hi(); # ok
say $TestPack::global; # ok
File TestPack.pm:
package TestPack;
use warnings;
use strict;
use feature 'say';
#use Exporter qw(import); # This is normally done to export symbols
#our #EXPORT_OK = qw(hi); # (unless the package is a class)
our $global = 7;
sub hi { say "hi from ", __PACKAGE__ }
1;
One needs to use fully qualified names for those symbols as they weren't imported. If the package exports symbols and we import some‡ then they go into the calling package's namespace so in the example above they'd be available in main::, so they can be accessed by any code in the interpreter by their exported names (hi, no need for TestPack::hi). One cannot access lexical variables from that package (created with my, our, state)§.
This also works if instead of the mere block (named TEST_SCOPE) we introduce another package, and require our TestPack inside of it.
...
package AnotherPack {
require TestPack;
...
1;
};
...
TestPack::hi(); # ok
...
(That package should be inside a BEGIN block really, what doesn't change the main point here.) Global symbols from TestPack are still accessible in main::, via their fully qualified names. The exported names, which we import along with require, are then available as such in this package, but not in main::.
Comments on the question
Package name (PERSON) and the filename for it (person.pm) have to agree. For example, the namespace (==package) Person is defined in the file Person.pm
This is about basics related to require-ing a package; it has nothing to do with object-oriented notions. (Even though, a class is firstly a package. See perlootut and perlobj.) Also see Packages in perlmod and our.
If you were to use a package that bless-es, the returned object (instance) is (assigned to) a lexical variable. As such, it doesn't exist outside of the scope. The package itself, though, is visible just as shown above but in object-oriented work we don't want to poke at a package's insides, but rather use methods via objects.
So yes, to work with that package outside of the scope in which it is require-ed you'd need to instantiate an object in that other scope as well. That would still work much like the example above -- we can use the package name, outside of scope in which it was required, to instantiate an object (try!), even though I'd raise questions of such design (see next)
This hints at a convoluted design though, bringing in packages inside scopes, at runtime (via require); what is the context? (And I hope it's not really in a while loop.)
† Print out the main's symbol table, %main:: (using Data::Dumper for example) and we find
"TestPack::" => *main::TestPack::
along with all other symbols from TestPack namespace.
‡ If a package exports symbols and we require the package then we can import by
require Pack::Name;
Pack::Name->import( qw(subname anothername ...) );
§ Note that our creates a lexical which is an alias for a package variable, which is accessible.
zdim's answer gives a very good explanation of how package variables work and can be used. I don't think it directly answers the question of when they fall out of scope though.
Succinctly:
Package variables are global static variables, just namespaced so the "global" aspect isn't as terrible.
As with any static variable, they are in scope for the entire execution of the program.
You also asked:
In my understanding of other more object oriented languages you would need to declare a new object instance, maybe with its own constructor/initialization functions to use "package" variables. That doesn't seem to be the case here with Perl.
Package variables are fairly unrelated to object-oriented programming in Perl. They are not used for storing instance data. (Except sometimes in the case of inside-out objects, though that's more of an advanced topic.)

Perl - nest modules and access subroutines from 2nd level nested modules in main script

Is possible in perl to nest modules and export all nested subroutines to script which uses parent module? Consider following example:
Main script will use subroutines from ParentModule. So in script will be following line:
use ParentModule;
ParentModule will use subroutines from ChildModule. So in ParentModule will be following line:
use ChildModule;
Will subroutines exported under ChildModule available under main script?
Some times ago I've asked similar question here and answer was no, but this is quiet different than it was meant before. Also I have tried the scenario described above and it did not worked. Is there any another way how to do it?
PS: All modules uses exporter.
Thank you
ParentModule will need to explicitly provide the ChildModule symbols for export. Since you are using Exporter, the easiest way to do that is:
In ChildModule.pm:
package ChildModule;
use strict;
use warnings;
use base 'Exporter';
our #EXPORT = ( 'cf' );
sub cf { print "Child\n" }
1;
In ParentModule.pm:
package ParentModule;
use strict;
use warnings;
use base 'Exporter';
use ChildModule;
our #EXPORT = ( 'pf', #ChildModule::EXPORT );
sub pf { print "Parent\n" }
1;
Then,
% perl -MParentModule -e 'pf; cf'
Parent
Child
It's not typically good form to export things by default, though. You can play the same tricks with #EXPORT_OK, but you will still need to explicitly import the ChildModule routines into ParentModule or ParentModule won't be able to export them.
There are other modules which allow you to avoid that last step (e.g. Import::Into) but you'll need to craft a custom import() routine in ParentModule if you want to retain the simple use ParentModule statement.

use symbols from module without package (require)

I already asked a similar question, but it had more to do with using barewords for functions. Basically, I am refactoring some of my code as I have begun learning about "package" and OOP in perl. Since none of my modules used "package" I could just "require" them into my code, and I was able to use their variables and functions without any trouble. But now I have created a module that I will be using as a class for object manipulation, and I want to continue being able to use my functions in other modules in the same way. No amount of reading docs and tutorials has quite answered my question, so please, if someone can offer an explanation of how it works, and why, that would go a really long way, more than a "this is how you do it"-type answer.
Maybe this can illustrate the problem:
myfile.cgi:
require 'common.pm'
&func_c('hi');
print $done;
common.pm:
$done = "bye";
sub func_c {print #_;}
will print "hi" then "bye", as expected.
myfile_obj.cgi:
use common_obj;
&func_obj('hi');
&finish;
common_obj.pm:
package common_obj;
require 'common.pm';
sub func_obj {&func_c(#_);}
sub finish {print $done;}
gives "Undefined subroutine func_c ..."
I know (a bit) about namespaces and so on, but I don't know how to achieve the result I want (to get func_obj to be able to call func_c from common.pm) without having to modify common.pm (which might break a bunch of other modules and scripts that depend on it working the way it is). I know about use being called as a "require" in BEGIN along with its import().. but again, that would require modifying common.pm. Is what I want to accomplish even possible?
You'll want to export the symbols from package common_obj (which isn't a class package as it stands).
You'll want to get acquainted with the Exporter module. There's an introduction in Modern Perl too (freely available book, but consider buying it too).
It's fairly simple to do - if you list functions in #EXPORT_OK then they can be made available to someone who uses your package. You can also group functions together into named groups via EXPORT_TAGS.
Start by just exporting a couple of functions, list those in your use statement and get the basics. It's easy enough then.
If your module was really object-oriented then you'd access the methods through an object reference $my_obj->some_method(123) so exporting isn't necessary. It's even possible for one package to offer both procedural/functional and object-oriented interfaces.
Your idea of wrapping old "unsafe" modules with something neater seems a sensible way to proceed by the way. Get things under control without breaking existing working code.
Edit : explanation.
If you require a piece of unqualified code then its definitions will end up in the requiring package (common_obj) but if you restrict code inside a package definition and then use it you need to explicitly export definitions.
You can use common_obj::func_obj and common_obj::finish. You just need to add their namespaces and it will work. You don't need the '&' in this case.
When you used the package statement (in common_obj.pm) you changed the namespace for the ensuing functions. When you didn't (in common.pm) you included the functions in the same namespace (main or common_obj). I don't believe this has anything to do with use/require.
You should use Exporter. Change common_obj to add:
use base Exporter;
#EXPORT_OK = qw/func_obj finish/;
Then change myfile_obj:
use common_obj qw/func_obj finish/;
I am assuming you are just trying to add a new interface into an old "just works" module. I am sure this is fraught with problems but if it can be done this is one way to do it.
It's very good that you're making the move to use packages as that will help you a lot in the future. To get there, i suggest that you start refactoring your old code as well. I can understand not wanting to have to touch any of the old cgi files, and agree with that choice for now. But you will need to edit some of your included modules to get where you want to be.
Using your example as a baseline the goal is to leave myfile.cgi and all files like it as they are without changes, but everything else is fair game.
Step 1 - Create a new package to contain the functions and variables in common.pm
common.pm needs to be a package, but you can't make it so without effecting your old code. The workaround for this is to create a completely new package to contain all the functions and variables in the old file. This is also a good opportunity to create a better naming convention for all of your current and to be created packages. I'm going to assume that maybe you don't have it named as common.pm, but regardless, you should pick a directory and name that bits your project. I'm going to randomly choose the name MyProject::Core for the functions and variables previously held in common.pm
package MyProject::Core;
#EXPORT = qw();
#EXPORT_OK = qw($done func_c);
%EXPORT_TAGS = (all => [#EXPORT, #EXPORT_OK]);
use strict;
use warnings;
our $done = "bye";
sub func_c {
print #_, "\n";
}
1;
__END__
This new package should be placed in MyProject/Core.pm. You will need to include all variables and functions that you want exported in the EXPORT_OK list. Also, as a small note, I've added return characters to all of the print statements in your example just to make testing easier.
Secondly, edit your common.pm file to contain just the following:
use MyProject::Core qw(:all);
1;
__END__
Your myfile.cgi should work the same as it always does now. Confirm this before proceeding.
Next you can start creating your new packages that will rely on the functions and variables that used to be in the old common.pm. Your example common_obj.pm could be recoded to the following:
package common_obj;
use MyProject::Core qw($done func_c);
use base Exporter;
#EXPORT_OK = qw(func_obj finish);
use strict;
use warnings;
sub func_obj {func_c(#_);}
sub finish {print "$done\n";}
1;
__END__
Finally, myfile_obj.cgi is then recoded as the so:
use common_obj qw(func_obj finish);
use strict;
use warnings;
func_obj('hi');
finish();
1;
__END__
Now, I could've used #EXPORT instead of #EXPORT_OK to automatically export all the available functions and variables, but it's much better practice to only selectively import those functions you actually need. This method also makes your code more self-documenting, so someone looking at any file, can search to see where a particular function came from.
Hopefully, this helps you get on your way to better coding practices. It can take a long time to refactor old code, but it's definitely a worthwhile practice to constantly be updating ones skills and tools.

Perl: Dynamic module loading, object inheritance and "common helper files"

In a nutshell I try to model a network topology using objects for every instance in the network. Additionally I got a top-level manager class responsible for, well, managing these objects and performing integrity checks. The filestructure looks like this (I left out most of the object-files as they are all structured pretty equal):
Manager.pm
Constants.pm
Classes/
+- Machine.pm
+- Node.pm
+- Object.pm
+- Switch.pm
Coming from quite a few years in OOP, I'm a fan of code reuse etc. so I set up inheritance between thos objects, the inheritance tree (in this example) looks like this:
Switch -+-> Node -+-> Object
Machine -+
All those objects are structured like this:
package Switch;
use parent qw(Node);
sub buildFromXML {
...
}
sub new {
...
}
# additonal methods
Now the interesting part:
Question 1
How can I ensure correct loading of all those objects without typing out the names statically?
The underlying problem is: If I just require "$_" foreach glob("./Classes/*"); I get many "Subroutine new redefined at" errors. I also played around with use parent qw(-norequire Object), Module::Find and some other #INC modifications in various combinations, to make it short: It didn't work. Currently I'm statically importing all used classes, they auto-import their parent classes.
So basically what I'm asking: What is the (perl-)correct way of doing this?
And advanced: It would be very helpful to be able to create a more complex folder structure (as there will be quite a few objects) and still have inheritance + "autoloading"
Question 2 - SOLVED
How can I "share my imports"? I use several libraries (my own, containing some helper functions, LibXML, Scalar::Util, etc.) and I want to share them amongst my objects. (The reasoning behind that is, I may need to add another common library to all objects and chances are high that there will be well above 100 objects - no fun editing all of them manually and doing that with a regex / script would theoretically work but that doesn't seem like the cleanest solution available)
What I tried:
import everything in Manager.pm -> Works inside the Manager package - gives me errors like "undefined subroutine &Switch::trace called"
Create a include.pl file and do/require/use it inside every object - gives me the same errors.
Some more stuff I sadly don't remember
include.pl basically would look like that:
use lib_perl;
use Scalar::Util qw(blessed);
use XML::LibXML;
use Data::Dumper;
use Error::TryCatch;
...
Again I ask: What's the correct way to do it? Am I using the right approach and just failing at the execution or should I change my structure completely?
It doesn't matter that much why my current code doesn't work that well, providing a correct, clean approach for those problems would be enough by far :)
EDIT: Totally forgot perl version -_- Sidenote: I can't upgrade perl, as I need libraries that are stuck with 5.8 :/
C:\> perl -version
This is perl, v5.8.8 built for MSWin32-x86-multi-thread
(with 50 registered patches, see perl -V for more detail)
Copyright 1987-2006, Larry Wall
Binary build 820 [274739] provided by ActiveState http://www.ActiveState.com
Built Jan 23 2007 15:57:46
This is just a partial answer to question 2, sharing imports.
Loading a module (via use) does two things:
Compiling the module and installing the contents in the namespace hierarchy (which is shared). See perldoc -f require.
Calling the import sub on each loaded module. This loads some subs or constants etc. into the namespace of the caller. This is a process that the Exporter class largely hides from view. This part is important to use subs etc. without their full name, e.g. max instead of List::Util::max. See perldoc -f use.
Lets view following three modules: A, B and User.
{
package A;
use List::Util qw(max);
# can use List::Util::max
# can use max
}
{
package User;
# can use List::Util::max -> it is already loaded
# cannot use max, this name is not defined in this namespace
}
Package B defines a sub load that loads a predefined list of modules and subs into the callers namespace:
{
package B;
sub load {
my $package = (caller())[0]; # caller is a built-in, fetches package name
eval qq{package $package;} . <<'FINIS' ;
use List::Util qw(max);
# add further modules here to load
# you can place arbitrarily complex code in this eval string
# to execute it in all modules that call this sub.
# (e.g. testing and registering)
# However, this is orthogonal to OOP.
FINIS
if ($#) {
# Do error handling
}
}
}
Inside the eval'd string, we temporarily switch into the callers package and then load the specified module. This means that the User package code now looks like this:
{
package User;
B::load();
# can use List::Util::max
# can use max
}
However, you have to make sure the load sub is already loaded itself. use B if in doubt. It might be best to execute B::load() in the BEGIN phase, before the rest of the module is compiled:
{
package User;
BEGIN {use B; B::load()}
# ...
}
is equivalent to
{
package User;
use B;
use List::Util qw(max);
# ...
}
TIMTOWTDI. Although I find evaling code quite messy and dangerous, it is the way I'd pursue in this scenario (rather than doing files, which is similar but has different side effects). Manually messing with typeglobs in the package namespace is hell in comparision, and copy-pasting a list of module names is like going back to the days when there wasn't even C's preprocessor.
Edit: Import::Into
… is a CPAN module providing this functionality via an interesting method interface. Using this module, we would redefine our B package the following way:
{
package B;
use List::Util; # you have to 'use' or 'require' this first, before using 'load'.
use Import::Into; # has to be installed from CPAN first
sub load {
my $package = caller;
List::Util->import::into($package, qw(max));
# should work too: strict->import::into($package);
# ...
}
}
This module hides all the dirty work (evaling) from view and does method call resolution gymnastics to allow importing pragmas into other namespaces.
Addendum to Import::Into Solution
I found a scenario that seems to require eval() from within the Import::Into solution. In this scenario, mod User is effectively among the uses from package B. This may be a common scenario for people using Import::Into.
Specifics:
I created module uses_exporter with separate subs for importing
different groups of modules, e.g. load_generic() and
load_list_utils().
The uses in load_list_utils() are to public mods like
List::MoreUtils, AND to a module of my own, list_utils_again. That
local module also calls load_list_utils(). The call fails if
load_list_utils() uses list_utils_again.
My solution was to put the use to list_utils_again into an eval which
does not excecute when $target eq 'list_utils_again'
The correct idiomatic Perl way to do this is not to always load a bunch a modules whether used or not; it is to have every file use those modules it directly (not indirectly) needs.
If it turns out that every file uses the same set of modules, you might make things simpler by having a single dedicated module to use all those in that common set.

How can I make a module that imports many modules for the user?

I have a rather complex data structure I've implemented in Perl. This has been broken up into about 20 classes. Basically, any time you want to use one of these classes, you need to use all of them.
Right now, if someone wants to use this data structure, they need to do something like:
use Component::Root;
use Component::Foo;
use Component::Bar;
use Component::Baz;
use Component::Flib;
use Component::Zen;
use Component::Zen::Foo;
use Component::Zen::Bar;
use Component::Zen::Baz;
... # 15 more of these...
use Component::Last;
to be able to manipulate all parts of it. How can I write a module that does this for the user, so all they have to do is
use Component;
to get all of the other modules imported?
In this particular case, the modules are all classes and don't have exports.
If these are just classes (i.e. they don't export any functions or variables when you use them), then all that really matters is that they have been loaded.
Just create Component.pm:
package Component;
our $VERSION = '1.00';
use Component::Root;
use Component::Foo;
use Component::Bar;
use Component::Baz;
use Component::Flib;
use Component::Zen;
use Component::Zen::Foo;
use Component::Zen::Bar;
use Component::Zen::Baz;
... # 15 more of these...
use Component::Last;
1; # Package return value
You don't need Exporter or anything like it.
However, instead of having a module that is nothing but use statements, it probably makes more sense to put those use statements into the class of the root node, or into the module that creates the data structure. That is, people will want to say:
use Component::Root;
my $root = Component::Root->new(...);
or
use Component qw(build_structure);
my $root = build_structure(...);
depending on how your data structure is normally created. It might be a bit confusing for people to write:
use Component;
my $root = Component::Root->new(...);
but it really depends on what your API looks like. If there are a number of classes that people might be calling new on, then use Component might be the way to go.
You could use the export_to_level method for all those packages that are Exporters.
MyPackage->export_to_level($where_to_export, $package, #what_to_export);
You could also just export all the symbols you import.
use PackageA qw<Huey Dewey Louie>;
...
our #ISA = qw<Exporter>; #inherit Exporter
our #EXPORT = qw<Huey Dewey Louie>;
However, if you don't want to export any symbols, and just want to load modules, then just include those use statements above, and any package in the process will be able to instantiate them as classes, say if they were all OO modules.
Provided that they have been loaded successfully, they will exist in %INC and the symbol table.
Moose::Exporter seems to do this, although all your other modules will have to use it as well.
In Component:
Moose::Exporter->setup_import_methods(
also => [qw/Component::Root Component::..*/],
);
If the modules do not export anything and don't have an import method (same requirements as cjm's answer) you just need to load the modules without import:
package Component;
our $VERSION = '1.00';
require Component::Root;
require Component::Foo;
require Component::Bar;
require Component::Baz;
require Component::Flib;
require Component::Zen;
require Component::Zen::Foo;
require Component::Zen::Bar;
require Component::Zen::Baz;
... # 15 more of these...
require Component::Last;
1; # Package return value
The users of the module will just do:
require Component;
If however some modules do exports, you will have to call their import method. So you have add an import method in your Component module that will call them:
sub import
{
Component::Root->import;
Component::Foo->import;
...
}
and so the module users will have to use it:
use Component;
Note that you may have to use some other tricks if the imported module has to insert symbols in the importer's context. See for example how the POE's import does it.
The Modern::Perl module touts itself with “enable all of the features of Modern Perl with one command,” where that command is
use Modern::Perl;
and those features are
For now, this only enables the strict and warnings pragmas, as well as all of the features available in Perl 5.10. It also enables C3 method resolution order; see perldoc mro for an explanation.
That's a lot for one line of code, which according to the perlmod documentation is exactly equivalent to
BEGIN { require Module; import Module; }
Consider Modern::Perl's implementation:
package Modern::Perl;
our $VERSION = '1.03';
use 5.010_000;
use strict;
use warnings;
use mro ();
use feature ();
sub import {
warnings->import();
strict->import();
feature->import( ':5.10' );
mro::set_mro( scalar caller(), 'c3' );
}
1; # End of Modern::Perl
To adapt this to your situation, from your top-level module use all the other modules you want to load, and call their imports, if any, from MyTopLevelModule::import.
Note that you don't necessarily need to copy
use 5.010_000;
into MyTopLevelModule.pm, but that would be a fine idea! According to the use documentation:
In the peculiar use VERSION form, VERSION may be either a positive decimal fraction such as 5.006, which will be compared to $], or a v-string of the form v5.6.1, which will be compared to $^V (aka $PERL_VERSION). An exception is raised if VERSION is greater than the version of the current Perl interpreter; Perl will not attempt to parse the rest of the file. Compare with require, which can do a similar check at run time.