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

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.

Related

Importing subroutines from parent class

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.

Subroutines defined in required file assigned to wrong namespace after use of custom module

In a script I am working on, I have something similar to the following:
require "environment.pm"; # Various definitions, including subroutine get_coll()
use Custom::Module;
In the Custom::Module file, I start with
package Custom::Module;
and end with
1;
When I try to call get_coll() I get an error about it:
( main::get_coll() ) being undefined.
If I require Custom::Module instead of using or change the call to be
Custom::Module::get_coll();
it works fine. This leads me to be believe that the "use" statement of CustomModule is changing the "active" namespace so when get_coll() is processed (since it is processed at the time of calling) it gets assigned to that namespace instead of main. This doesn't seem to be an issue with regular perl modules, but from the ones I've looked through, I haven't noticed anything different that would cause the namespace to "revert" back to main after the module has loaded. Any help in better understanding the namespace usage or fixing the module to not cause this problem would be greatly appreciated.
Side note: It isn't a huge issue for me to just "require" the module, but it was unexpected behavior to me so I mostly just want to better understand why what happened happened.
I've tried to recreate the files exactly as you describe them. Here are my three source files
You say
In a script I am working on, I have something similar to the following:
require "environment.pm"; # Various definitions, including subroutine get_coll()
use Custom::Module;
and
When I try to call get_coll() I get an error about it
Although you don't say where you're calling get_coll, I guess it's in the main script and I think that amounts to this script file
my_script.pl
use strict;
use warnings;
use 5.010;
require 'environment.pm';
use Custom::Module;
say get_coll();
and this module file
environment.pm
use strict;
use warnings;
use 5.010;
sub get_coll {
return 'coll';
}
1;
And then you say
In the Custom::Module file, I start with
package Custom::Module;
and end with
1;
So I wrote this module file. It doesn't have any contents because you didn't describe any
Custom/Module.pm
use strict;
use warnings;
use 5.010;
package Custom::Module;
1;
Now, when I run my_script.pl I get
coll
with no warnings or error messages, which is exactly as I expected
I am concerned that you say environment.pm contains get_coll, yet you are able to call Custom::Module::get_coll. Does Custom/Module.pm also have a require 'environment.pm'?
If you can point out where I have misinterpreted your description then please do, as I cannot replicate your problem at present and so am unable to help you
Otherwise, I recommend that you play with these three files to create a Short, Self-Contained, Correct Example of your problem. That will help us enormously to find a solution for you
You are mistaken about require being any different from use with respect to what namespace subroutines get defined in. It is not. And you are mistaken about use affecting the current package. It does not.
# Custom/Module.pm
package Custom::Module;
# the namespace is now "Custom::Module"
sub foo { ... } # defines &Custom::Module::foo
sub bar { ... } # defines &Custom::Module::bar
1; # end of Custom/Module.pm
---
# mainScript.pl
# without an explicit 'package' statement, we are in namespace "main"
use Custom::Module; # parses Custom/Module.pm
# but when the 'use' statement is complete, we are still in namespace "main"
sub baz { ... } # defines &main::baz
$x = baz(); # calls &main::baz
$y = foo(); # calls &main::foo, error if main::foo not defined
$z = Custom::Module::bar(); # calls &Custom::Module::bar
...
The comments describe what namespace we are in in each part of each file. None of that would be any different if we said require Custom::Module instead of use Custom::Module.
Now it can be a hassle to keep typing Custom::Module::bar() all the time when there is no main::bar() and there's no ambiguity about which bar subroutine you would be referring to. The key to getting perl to recognize your call to bar as referring to Custom::Module::bar is to copying the subroutine reference from Custom::Module into your current namespace. That is, making main::bar() refer to the same subroutine as Custom::Module::bar().
The canonical way to do this is with the Exporter module. The low level way to do this (and what Exporter does behind the scenes) is to manipulate perl's symbol tables.
For your specific problem, you would use Exporter like this:
# Custom/Module.pm
package Custom::Module;
use base 'Exporter'; # make Custom::Module inherit from Exporter
our #EXPORT = qw(foo bar);
sub foo { ... }
sub bar { ... }
...
1;
Now any other file that calls use Custom::Module will get the function get_coll imported into its namespace. This gets done behind the scenes in Exporter by manipulating the symbol table. Specifically, calling use Custom::Module from package main will get Exporter to make a typeglob assignment like
*main::foo = *Custom::Module::foo;
and this will make your function call from main::foo() invoke the code that was defined in Custom::Module::foo().

export vs export_ok in perl

I can not understand what is the difference/use case of EXPORT_OK vs EXPORT.
Most resources mentions something in the lines of:
#Export allows to export the functions and variables of modules to
user’s namespace using the standard import method. This way, we don’t
need to create the objects for the modules to access its members.
#EXPORT_OK does export of symbols on demand basis for selective list
of symbols (subroutines and variables) of the module.
But I really don't see the difference/meaning here.
Can someone please provide a small fundamental example of the difference/usage of these 2 symbols?
Let's say I have a package MyPackage that uses #EXPORT.
#this is MyPackage.pm
package MyPackage;
#EXPORT = qw(do_awesome_thing);
sub do_awesome_thing { ... }
sub be_awesome { ... }
Now, when I use MyPackage in my code,
#this is myscript.pl
use MyPackage;
do_awesome_thing(); #works
be_awesome(); #doesn't work
MyPackage::be_awesome(); #works
do_awesome_thing gets automatically exported to my code from MyPackage, without me having to say "give this to me". be_awesome isn't exported (and it won't be exported with #EXPORT_OK either, I'm just showing that part to get you clear on what "exporting" gives us).
On the other hand, if I have a package MyOtherPackage that uses #EXPORT_OK,
#this is MyOtherPackage.pm
package MyOtherPackage;
#EXPORT_OK = qw(do_awesome_thing);
sub do_awesome_thing { ... }
sub be_awesome { ... }
and then try
#this is mynewscript.pl
use MyOtherPackage;
do_awesome_thing(); #doesn't work
MyOtherPackage::do_awesome_thing(); #works, as always
the line calling do_awesome_thing directly won't work. This is because putting something in #EXPORT_OK says "give this to my users only if they ask for it". Since we've just said use MyOtherPackage without explicitly asking for do_awesome_thing to be imported here, it doesn't get imported, and is accessible only by specifying the package name.
The way you ask for do_awesome_thing to be imported is to say use MyOtherPackage qw(do_awesome_thing) in the second line of mynewscript.pl above. This says import that module and make do_awesome_thing available directly. After that, the fourth line in mynewscript.pl above will start working.
Note that the user can specify use MyPackage qw(do_awesome_thing) with the first package also, and in that case, anything else in the #EXPORT list won't be exported, only do_awesome_thing will be. So, except for the default case of use PackageName;, #EXPORT and #EXPORT_OK behave similarly. In the default case, anything in #EXPORT gets thrown into the user's script automatically, while #EXPORT_OK is more polite and doesn't export anything.
From the fine Exporter manual:
use YourModule;
This imports all the symbols from YourModule's #EXPORT into the namespace of the use statement.
use YourModule ();
This causes perl to load your module but does not import any symbols.
use YourModule qw(...);
This imports only the symbols listed by the caller into their namespace. All listed symbols must be in your #EXPORT or #EXPORT_OK, else an error occurs. The advanced export features of Exporter are accessed like this, but with list entries that are syntactically distinct from symbol names.
So, if you use #EXPORT and someone does the usual use YourModule;, then you've just polluted their namespace with everything in #EXPORT. But, if you use #EXPORT_OK, they have to specifically ask for things to be imported so the person using your module has control over what happens to their namespace.
The difference is really a matter of who controls what gets into the user's namespace: if you use #EXPORT then the module being used does, if you use #EXPORT_OK then the code doing the import controls their own namespace.
Of course, you could always say use Whatever(); to keep impolite modules from polluting your namespace but that's ugly and you shouldn't have to kludge around rude code that wants to scribble all over your namespace.

Prevent multiple inclusions in perl

Suppose I have two files: a module file that looks like this:
package myPackage;
use Bio::Seq;
and another file that looks like this:
use lib "path/to/lib";
use myPackage;
use Bio::Seq;
How can i prevent that Bio::Seq is included twice? Thanx
It won't be included twice. use semantics could be described like that:
require the module
call module's import
As the documentation says, it's equivalent to:
BEGIN { require Module; Module−>import( LIST ); }
require mechanism, on the other hand, assures modules' code is compiled and executed only once, the first time some require it. This mechanism is based on the special variable %INC. You can find further details in the documentation for use, require, and in the perlmod page.
use Foo
is mostly equivalent to
# perldoc -f use
BEGIN {
require "Foo.pm";
Foo->import();
}
And require "Foo" is mostly equivalent to
# perldoc -f require
sub require {
my ($filename) = #_;
if (exists $INC{$filename}) {
return 1 if $INC{$filename};
die "Compilation failed in require";
}
# .... find $filename in #INC
# really load
return do $realfilename;
}
So
No, the code won't be "Loaded" more than once, only "imported" more than once.
If you have code such as
package Bio::Seq;
...
sub import {
# fancy stuff
}
And you wanted to make sure a library was loaded, but not call import on it,
#perldoc -f use
use Bio::Seq ();
Modules aren't "included" in Perl like they are in C. They are "loaded", by which I mean "executed".
A module will only be loaded/executed once, no matter how many use statements specify it.
The only thing that happens for every use of a module is the call to the module's import method. That is typically used to export symbols to the using namespace.
I guess, you want to optimize the loading(usage) of Module.
For optimizing, dynamic loading may be helpful.
For dynamically loading a Perl Module, we use Class::Autouse.
For more details you can visit this link.
I guess the OP may look for a way of avoiding a long list of use statement boilerplate at the beginning of his/her Perl script. In this case, I'd like to point everyone to Import::Into. It works like the keyword import in Java and Python. Also, this blog post provides a wonderful demo of Import::Into.

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.