Softpanorama

May the source be with you, but remember the KISS principle ;-)
Home Switchboard Unix Administration Red Hat TCP/IP Networks Neoliberalism Toxic Managers
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and  bastardization of classic Unix

Perl modules

 News

Books

Recommended Links Recommended Articles CPAN Perl namespaces  

 

Getopt::Std Getopt::Long Net::ftp Net::netrc Benchmark Net::Telnet File::Find  
 Expect.pm Reimplementation of Unix tools Pipes in Perl Debugging Tips Beautifiers Humor Etc

Perl module is a package usually stored as a separate file. As such each module uses its own namespace. Within this namespace you can have a  collection of subroutines and variables that can be used from mail script or other modules. 

Variables in modules are initialed as a part of particular main script startup. While they belong to a different namespace they exist till the script ends. In this sense,  they are not that different from variable initialed in main scripts.

As main  script and module uses separate namespace there should be some mechanism of exchanging information about symbol tables -- essentially mechanism for establishing aliases to module variable in the main script or other  module.  You can work without  aliases  as well, but  in this case you needd to  prefix each "external" variable with the namespace to which it belongs. I saw large packages that use this method.

But it is more convenient explicitly export all the necessary variables from the module and import them in the main script or other modules. This way you essentially define the interface or API of the module.  You can export more variables then you import. For example, for particular usage only a small subset of exported variables is needed. Perl provide "conditional exporting" that solved this problem quite nicely -- in this  case variables are just marked as "exportable" without actually exporting them. So in the case the main script or other module need to specify explicit subset that is needed. 

Module usually consist of a set of variables that are used by all subroutines and the set of subroutines. If you want to think in terms of OO this is a class and methods, although this class has only a single instance of itself. 

 Usually not  all subroutines are exported, some are internal. To distinguish them internal subroutines of the module, the latter are usually named staring with underscore.

Technically, Perl module is just a set of conventions for using Perl's package mechanism. But this set of convention was universally adopted and became standard de-facto.  Usually prolog of the module looks like

use v5.10;
   use warnings;
   use strict 'subs';
   use feature 'state';

require Exporter;

our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
@ISA = qw(Exporter);
@EXPORT = qw(autocommit helpme abend banner logme out);

$VERSION = '1.10';

in this example we export in the main namespace  six subroutines named  autocommit helpme abend banner logme out

 This is done using an array @EXPORT which is used by the exporter module

A Module is a collection of related subroutines and data designed to be used by other programs or modules. Modules are defined in separate files and use the package keyword to define a namespace for the data and subroutines in that module file.

A Module can be a simple collection of subroutines, not defining a class. Such modules are referred to as libraries.

A Class is a user-defined data type. Classes are defined in modules  using special constructs that allow you to create variables of that type. The subroutines in these modules are referred to as methods.

An Object is a variable that belongs to a particular class. It contains its own, private data that can be operated on by the methods  defined in the class. The object is called an instance  of its class.

Example:

What's up with all the double colons (::)?  The :: corresponds to a filesystem path separator. A Module called Shape::Rect corresponds to a file named Shape/Rect.pm relative to a module library directory. 

Perl comes with a large library of modules. In recent versions it is essentially too big to be useful.  But you can be selective and find  modules in which programming style looks to you attractive and  study them

As modules use their own namespace they cannot conflict with variable in your code and thus they enhance code reuse.

A huge archive of Perl modules CPAN (Comprehensive Perl Archive Network) was collected over the time.

Some useful modules for system administration are:

use  is executed at compile time.

You load modules into your namespace using use statement. It is executed at compile time, not run time.  You can't use modules conditionally.

We can assume that statements in the body of the modules are executed at the initiation of the program/Script. So all variables are initialized at the moment the main script executes its first statement.

Exporters

Since module is a packagesstored in a file, a subroutine in the Text::Wrap module, for example, would normally be encapsulated in the namespace of Text::Wrap package.  So, for example, each call to subroutine justify would be  referenced in the main script as Text::Wrap::justify

However, let's say it would be more convenient for us to export the name of the subroutines in the namespace of the package we're currently in – usually the main package. To do this, Perl uses a special system module called Exporter , which created aliases on names in the module in the the caller's package namespace. 

When you use a module, as well as reading and executing the code, Perl will try and run a subroutine called import inside the module's package. If that's not found, nothing happens, and there's no error. If it is found, though, it's called with all the parameters given on the use line. So, for instance:

use Simple("Valid", "Fake");

loads the Simple module and then runs built-in subroutine import:

Simple::import("Valid", "Fake");

Theoretically, this import subroutine could do anything. In fact, a few modules use it to let you pass parameters to setup the module. However, you'll usually want to use it to import subroutines and variables.

Exporter lets the modules that use it borrow a standard import subroutine. This subroutine checks a number of variables inside the module as well as the parameters that we give it. If we give an empty list, like this:

use Simple ();
then nothing will be imported. In this case if we wan to call a particular subroutine, for example Valid()  we need call it as Simple::Valid().

@EXPORT and @EXPORT_OK array control export of names into outside namespace

Those two array allows to export the functions and variables of modules to the namespace where the  use statement is issued.  @EXPORT and @EXPORT_OK are the two main variables that control export of variable from the module to outside namespace.

If the name was defined in @EXPORT_OK the name can be exported but you need to do it explicitly by providing this name in the list of parameters in use statement. In other words it should be mentioned in use statement explicitly. 

For example it is common to list all subroutines that the module is prepared to export in this array. you do not necessary want to export all of them by default, as some of them are for special cases only. 

So if, for instance, I want to allow use subroutines Valid() , Fake()  without package qualification I need to populate the variable

package Simple; 
use warnings; 
use strict; 
use Exporter; # this is obligatory statement (module convention)
our @ISA = qw(Exporter); # this is obligatory statement (module convention)
our @EXPORT = qw(Test); # Optional, but typically is present; you need it only if you export some subroutines or variables expelisidly
our @EXPORT_OK = qw(Valid Fake); # Optional but typically is present. This is the list of variables and subroutines that you can export explisidly
#
# List of your variables and subroutines
#
sub Test { print "This is a test\n";
sub Valid { print "Valid\n" }
sub Fake { warn "Fake" }
EXPORT defines names that will be exported by default. In the example below, if we don't pass any parameters to use statement at all, only subroutine Fake that is defined in @EXPORT will be exported .
package Simple;
use warnings;
use strict;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(Valid Fake); # defaults
our @EXPORT = qw(Fake); # subroutnes
sub Valid { print "Valid" }
sub Fake { warn "Fake" }
and we ran
use Simple ; 

in our main program, we'd be able to call Fake() from the main program, but not Valid() or  – we would have to call these as Simple::Valid().

We can also define tags with the %EXPORT_TAGS hash. This allows us to group together a bunch of subroutines or variables under a group name. For instance, the CGI module allows us to say:

use CGI qw(:standard); 

which will import all its most useful subroutines.

use Exporter

The statement use Exporter lets you 'Export' functions and variables into the namespace where use statement was executed.

module Simple.pm:
package Simple;
sub Valid { print "Valid" }
sub Fake { warn "Fake" }

Now let's call subroutine Valid from the main script:

client (client.p):
use Simple;
print Simple::Valid(); 

We use print Simple::Valid(). We had to fully qualify the namespace to the function that we were using. If you exported this function instead, you could say:

use Simple;

print Valid();

without knowing that 'Valid()' was inside 'Simple'.

How to do this? Well, Perl provides Exporter  to do this very thing. You say:

module Simple.pm
package Simple;
use Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(Valid);

Don't worry about the mechanics of how this works for now. All  that means is 'Export the function Sub1  into any place that says "use Simple"' This is called 'Exporting by default'. When you say:

use SimpleCrypto;

in your script, what Perl does is load up SimpleCripto, and then magic happens, copying the PigLatin function into the namespace where 'use Simple' is called. 

Anyway, 'exporting by default' is not necessarily the best thing to do. There are two nasty things that can happen:

  1. You can forget about where your functions are coming from.  There is something more disciplined approach  to write SimpleCrypto::PigLatin() instead of 'PigLaticValid()', because you know exactly where to look in case of problems.
  2. Since there is a lot of stuff going on here ( inheritance, globbing, using the import function, etc) you are best off knowing about how it works, before actually using it.

The documentation has a lot more in the way of examples on 'use Exporter'. You don't need to necessarily 'export by default', you can export by choice, give a list of patterns to export (or not export) export variables, and so on. Go to the documentation for more information.

@INC and %INC

The best way to avoid problems with loading the wrong libraries or modules is to understand how Perl actually finds the libraries that it is to load into memory. We cover this in detail below.

The central variable here is called @INC  (short for include) and if you remember anything out of this section, remember this.

@INC

 is an array provided by Perl which tells Perl (and you) the directories to search to find libraries and modules. 90% of your problems with version mis-management can be solved by this simple statement put at the beginning of your program:

print "@INC\n";

This gives you a list of places that Perl is looking to find your libraries. Here is the central rule about @INC  that you should remember: Perl goes through each of the directories in order looking for the module or library that you are including. If it cannot find it in one directory, it goes to the next.

Printing out @INC  shows exactly in which order Perl will scan libraries for the name you provided in use statement. This is useful in trouble-shooting.

Suppose you have a use statement:

use Devel::Peek;

and you find out that Perl is saying something like:

Can't locate Devel::Peek in @INC at line

Well, the first thing to do is comment out the offending line (use Devel::Peek) to print out the "@INC\n" variable as the script sees it.

perl -e 'print "@INC\n"'
/usr/local/lib/perl5 /usr/local/lib/perl5/sun4-solaris . /home/joeuser/WORK/Devel

Now, in tracing this down, what we do is 'follow in Perl's footsteps'. Perl goes through the following machinations:

  1. Perl looks in /usr/local/lib/perl5, and checks if /usr/local/lib/perl5/Devel/Peek.pm exist
  2. Then is repeats this operation for all other directories in the list
  3. If at this point modules is not found it  gives up and issues an error.

NOTE:  If dot is present it means that directory from which the script is loaded.

No  we can see the error with the specification  of the last directory.  '/home/joeuser/WORK/Devel'. Because after concatenation we will get:

/home/joeuser/WORK/Devel/Devel/Peek.pm

So  there is an extra 'Devel' on the end of our @INC  which is causing this error. The simple solution therefore is to change @INC  to include /home/joeuser/WORK instead of /home/joeuser/WORK/Devel.

Array @INC and Perl's Process of Including Libraries

This is fairly straightforward if you understand "Perl-think". Learning include paths like Perl's will pay off tenfold (in other compilers, tools, etc.) It is quite a common design tactic in computer science.

Setting @INC

The variable @INC  is such an important beastie to Perl that there are several different ways of setting its value. Each way has its advantages and disadvantages, you should be aware of them all (especially when debugging projects!)

The Default Value of @INC

Unlike most variables in Perl, the default value of @INC  is not blank. Instead, it is a value that is set at the moment which Perl has been compiled. If you look inside the config.sh  file that comes with your Perl distribution, you will see this value.

Or, probably easier, the one line script

perl -e 'print "@INC\n"' 

will do the same.)

This path points to the place where the Perl installation has put all of the libraries that came with the standard distribution (see the namespace diagram up above).

The Environmental Variable PERL5LIB

The first way you should know about setting @INC  is via the environmental variable PERL5LIB. This is a good way to set the environment for the purposes of a cron job, or to set the environment temporarily so you can test out new code.

If you say something like:

$ export PERL5LIB = "my_path";

on ksh, then you prepend 'my_path' to the @INC  variable. Hence, if @INC  was:

"/usr/local/lib/perl5", "/usr/local/lib/perl5/sun-solaris"

it becomes:

"my_path", "/usr/local/lib/perl5", "/usr/local/lib/perl5/sun-solaris"

with 'my_path' being the first place that Perl will search for libraries.

Setting PERL5LIB  does have some drawbacks however. Since you are setting the environment rather than putting your instructions into the code itself, you have to be very careful when moving between environments. Forgetting to set PERL5LIB  is an easy thing to do, hence caution is advised.

use lib 'my_path'

'use lib "my_path"' is the second way to set @INC, and is probably the best, most stable way of doing it. It has the following benefits:

  1. It is done inside code, hence you see exactly what is going on.
  2. it works well with some Perl internals (in particular, MakeMaker, which you can read about in the Perl on-line documentation.)
  3. it uses a module, so your code will get benefits automatically of any further enhancements to the @INC  mechanism.

When you say:

use lib 'my_path';

at the beginning of any code, Perl does exactly the same thing as with PERL5LIB. Namely, it takes 'my_path' and prepends it to "@INC".

Setting @INC directly

Finally, we mention the fact that you can set @INC  directly, for closure. But to tell the truth, it is not such a good idea. You can say

BEGIN { unshift(@INC, "my_path"); }

which does the same thing as both PERL5LIB  and:

use lib "my_path"

but it is unclear, ugly, and non-encapsulated. (i.e.: it shows the guts of the logic rather than hiding the details).

So do yourself a favor and stick to the two other methods!

%INC.

@INC is fairly well known by people who program Perl regularly, but %INC  is not. This is unfortunate, because %INC  can be used to track down problems that would take a lot longer time to track down with @INC.

If @INC  contains a list of directories that Perl searches for modules, then %INC  contains a list of actual modules that Perl has loaded from the environment. For example, the following code:

use Benchmark;
foreach $key (sort keys(%INC)) {
print "$key => $INC{$key}\n";
}

will print out:

Benchmark => '/usr/local/lib/perl5/Benchmark.pm'

assuming that '/usr/local/lib/perl5' is the first library that Perl stumbles across.

As you can see, this can be extremely helpful. For one thing, it can save you the trouble of searching through the include path (@INC) to find a library out of sync, but more importantly it is exactly what Perl sees, so there is no chance of human error in tracing down these problems.

It also has one more benefit, one which you will get without any effort on your part, but you will be grateful for (trust me!). Take the following code:

for ($xx = 0; $xx < 10; $xx++) {
require "lib1.pl";
}

On the face of it, this code would cause the library lib1.pl to be included several times. In most languages, this would cause severe problems. C++, for instance, has 'compile guards' which are put around all header files. Something like this:

#ifndef HEADERA
#define HEADERA 1
#include "headera.h"
#endif

This is essentially a hack to prevent a header from being included several times (and getting 'xxx redefined' errors!).

Perl does not need this. Instead, each time a Perl library is included into your script, Perl records the fact inside %INC. The next time that library is encountered in require  or use, Perl recognizes that fact, and stops right there! Hence, no problems, and a vast saving of time and resources.

Anyway, let's use %INC  to solve another resource problem. Suppose that you have written a script, and get several weird errors, such as:

Undefined subroutine File::Path::seek() line ...

Now, File::Path is a module that you have written to do basic things like open a bunch of files (say in a 'tree' format), and when you open up the file 'File/Path.pm', and whatever else, you do see the subroutine named seek. Furthermore, the module 'File/Path.pm' is in your @INC  variable when you start Perl.

After a couple of minutes of double-checking yourself, your first reaction should be that this is a path problem. That somehow, you are including the wrong module into your program (Perl doesn't lie, after all!).

Therefore, you should insert the following line into your program:

foreach $key (sort keys(%INC)) { print "$key => $INC{$key}\n"; }

This is exactly like we did before, except now that we run the program, we see (in the midst of the output):

File::Path => /usr/local/lib/perl5/File/Path.pm

So, at a glance, you see that somehow, '/usr/local/lib/perl5' has a module 'File/Path.pm' instead of the expected '/home/joeuser/WORK' having 'File/Path.pm'. What has happened? You have gotten unlucky, and accidentally called your module the same name as one that is included in the central distribution! The solution? Rename your module File/MyPath.pm (and change the package definition inside) and everything compiles successfully.

In short, learning to use %INC  (and @INC) can mean hours of difference in effort. Problems like the one described above can be fairly common, especially in large, large, projects, and tracking them down can be trivial, or difficult, depending on your knowledge.

Summary of the Library and Module Road Map

@INC is the one major variable which is used to actually piece together script out of the several modules and libraries that are require'd and use'd by your program.

Perl looks at @INC  a directory at a time, trying to find modules. When it finds them, it notes the fact that it has found them in the hash %INC.

As @INC  is so important, there are several methods for setting @INC:

1) by default, Perl looks at how you have configured Perl to find the libraries that it needs.

2) by PERL5LIB, an environmental variable. This prepends a list of directories to @INC.

3) by saying 'use lib "path"' which changes @INC  at compile time.

Modules useful for system administrators

Useful modules for files and directories handling are:


Top Visited
Switchboard
Latest
Past week
Past month

NEWS CONTENTS

Old News ;-)

[May 09, 2021] How do I get the full path to a Perl script that is executing- - Stack Overflow

Jan 01, 2008 | stackoverflow.com

How do I get the full path to a Perl script that is executing? Ask Question Asked 12 years, 7 months ago Active 8 months ago Viewed 189k times

https://5a0213f7409d39e4f4257675bd947b2c.safeframe.googlesyndication.com/safeframe/1-0-38/html/container.html Report this ad


Chris Madden ,

172 38

I have Perl script and need to determine the full path and filename of the script during execution. I discovered that depending on how you call the script $0 varies and sometimes contains the fullpath+filename and sometimes just filename . Because the working directory can vary as well I can't think of a way to reliably get the fullpath+filename of the script.

Anyone got a solution? perl path location Share Improve this question Follow edited Feb 18 '15 at 12:18 serenesat 4,514 10 10 gold badges 32 32 silver badges 51 51 bronze badges asked Sep 17 '08 at 16:16 Chris Madden 2,202 2 2 gold badges 15 15 silver badges 11 11 bronze badges

user1210923 ,

I know this was a long time ago but I was just looking for a perl windows way of doing this and am quite happy with my solution #!/usr/bin/perl -w my @catalog= dir ; $myHome = substr($catalog[3],14); $myHome = &rtrim($myHome); print qq(<$myHome>\n); # Right trim function to remove trailing whitespace sub rtrim { my $string = shift; $string =~ s/\s+$//; return $string; } just thought I'd share – user1210923 Dec 4 '20 at 17:42

Drew Stephens , 2008-09-18 07:30:54

259

There are a few ways:

I've seen the first three ( $0 , the Cwd module and the FindBin module) fail under mod_perl spectacularly, producing worthless output such as '.' or an empty string. In such environments, I use __FILE__ and get the path from that using the File::Basename module:

use File::Basename;
my $dirname = dirname(__FILE__);
Share Improve this answer Follow edited Feb 12 '12 at 2:04 SamB 8,192 5 5 gold badges 43 43 silver badges 52 52 bronze badges answered Sep 18 '08 at 7:30 Drew Stephens 15.4k 12 12 gold badges 54 54 silver badges 81 81 bronze badges

Drew Stephens ,

This is really the best solution, especially if you already have a modified $0 – Caterham Jan 8 '12 at 1:04

Ovid , 2008-09-17 16:19:48

148

$0 is typically the name of your program, so how about this?

use Cwd 'abs_path';
print abs_path($0);

Seems to me that this should work as abs_path knows if you are using a relative or absolute path.

Update For anyone reading this years later, you should read Drew's answer . It's much better than mine. Share Improve this answer Follow edited Jul 4 '19 at 2:47 cxw 15.4k 2 2 gold badges 37 37 silver badges 69 69 bronze badges answered Sep 17 '08 at 16:19 Ovid 11.1k 7 7 gold badges 41 41 silver badges 75 75 bronze badges

GreenGiant ,

Small comment, on activestate perl on windows $0 typically contains backslashes and abs_path returned forward slashes, so a quick "tr /\//\\/;" was needed to fix it. – Chris Madden Sep 17 '08 at 17:03

Mark ,

35
Use File::Spec;
File::Spec->rel2abs( __FILE__ );

http://perldoc.perl.org/File/Spec/Unix.html Share Improve this answer Follow edited Aug 19 '13 at 21:32 the Tin Man 151k 39 39 gold badges 197 197 silver badges 279 279 bronze badges answered Sep 17 '08 at 16:31 Mark 101k 16 16 gold badges 158 158 silver badges 219 219 bronze badges

David H. ,

Then wrap in dirname() to get the absolute path - just what I needed! – David H. Oct 4 '19 at 4:03

bmdhacks , 2008-09-17 16:22:39

16

I think the module you're looking for is FindBin:

#!/usr/bin/perl
use FindBin;

$0 = "stealth";
print "The actual path to this is: $FindBin::Bin/$FindBin::Script\n";
Share Improve this answer Follow answered Sep 17 '08 at 16:22 bmdhacks 15.1k 8 8 gold badges 32 32 silver badges 55 55 bronze badges

> ,

Add a comment

Benjamin W. Smith ,

11

You could use FindBin , Cwd , File::Basename , or a combination of them. They're all in the base distribution of Perl IIRC.

I used Cwd in the past:

Cwd:

use Cwd qw(abs_path);
my $path = abs_path($0);
print "$path\n";
Share Improve this answer Follow edited Oct 8 '08 at 7:13 brian d foy 121k 31 31 gold badges 192 192 silver badges 549 549 bronze badges answered Sep 17 '08 at 16:29 Benjamin W. Smith 512 2 2 silver badges 6 6 bronze badges

Znik ,

@bmdhacks, you're right. Presumption is, you didn't change 0$. For example you do work above as soon as script starts (in initialization block), or elsewhere when you don't change $0. But $0 is excellent way to change process description visible under 'ps' unix tool :) This can show curren process status, etc. This is depended on programmer purpose :) – Znik Mar 3 '14 at 12:24

Eric Wilhelm ,

9

Getting the absolute path to $0 or __FILE__ is what you want. The only trouble is if someone did a chdir() and the $0 was relative -- then you need to get the absolute path in a BEGIN{} to prevent any surprises.

FindBin tries to go one better and grovel around in the $PATH for something matching the basename($0) , but there are times when that does far-too-surprising things (specifically: when the file is "right in front of you" in the cwd.)

File::Fu has File::Fu->program_name and File::Fu->program_dir for this. Share Improve this answer Follow edited Aug 19 '13 at 21:31 the Tin Man 151k 39 39 gold badges 197 197 silver badges 279 279 bronze badges answered Sep 18 '08 at 7:45 Eric Wilhelm 483 2 2 silver badges 2 2 bronze badges

Znik ,

Is it really likely that anyone would be so foolish as to (permanently) chdir() at compile time? – SamB Feb 12 '12 at 21:23

wnoise , 2008-09-17 16:52:24

7

Some short background:

Unfortunately the Unix API doesn't provide a running program with the full path to the executable. In fact, the program executing yours can provide whatever it wants in the field that normally tells your program what it is. There are, as all the answers point out, various heuristics for finding likely candidates. But nothing short of searching the entire filesystem will always work, and even that will fail if the executable is moved or removed.

But you don't want the Perl executable, which is what's actually running, but the script it is executing. And Perl needs to know where the script is to find it. It stores this in __FILE__ , while $0 is from the Unix API. This can still be a relative path, so take Mark's suggestion and canonize it with File::Spec->rel2abs( __FILE__ ); Share Improve this answer Follow edited Aug 19 '13 at 21:30 the Tin Man 151k 39 39 gold badges 197 197 silver badges 279 279 bronze badges answered Sep 17 '08 at 16:52 wnoise 9,310 32 32 silver badges 46 46 bronze badges

felwithe ,

__FILE__ still gives me a relative path. i.e. '.'. – felwithe Nov 2 '16 at 21:46

Sean , 2008-09-17 16:21:33

6

Have you tried:

$ENV{'SCRIPT_NAME'}

or

use FindBin '$Bin';
print "The script is located in $Bin.\n";

It really depends on how it's being called and if it's CGI or being run from a normal shell, etc. Share Improve this answer Follow answered Sep 17 '08 at 16:21 Sean 4,433 1 1 gold badge 17 17 silver badges 17 17 bronze badges

Znik ,

$ENV{'SCRIPT_NAME'} is empty when the script is running at console – Putnik Feb 6 '14 at 14:03

Matt , 2013-07-18 23:12:45

6

In order to get the path to the directory containing my script I used a combination of answers given already.

#!/usr/bin/perl
use strict;
use warnings;
use File::Spec;
use File::Basename;

my $dir = dirname(File::Spec->rel2abs(__FILE__));
Share Improve this answer Follow answered Jul 18 '13 at 23:12 Matt 61 1 1 silver badge 1 1 bronze badge

> ,

Add a comment

moritz , 2008-09-17 16:34:54

2

perlfaq8 answers a very similar question with using the rel2abs() function on $0 . That function can be found in File::Spec. Share Improve this answer Follow edited Aug 19 '13 at 21:31 the Tin Man 151k 39 39 gold badges 197 197 silver badges 279 279 bronze badges answered Sep 17 '08 at 16:34 moritz 12.3k 1 1 gold badge 36 36 silver badges 62 62 bronze badges

> ,

Add a comment

daniel souza ,

2

There's no need to use external modules, with just one line you can have the file name and relative path. If you are using modules and need to apply a path relative to the script directory, the relative path is enough.

$0 =~ m/(.+)[\/\\](.+)$/;
print "full path: $1, file name: $2\n";
Share Improve this answer Follow answered Jul 1 '14 at 16:19 daniel souza 332 2 2 silver badges 11 11 bronze badges

Keve ,

It does not provide the proper full path of the script if you run it like "./myscript.pl", as it would only show "." instead. But I still like this solution. – Keve Jun 27 '16 at 10:12

mkc , 2012-11-26 14:01:34

1
#!/usr/bin/perl -w
use strict;


my $path = $0;
$path =~ s/\.\///g;
if ($path =~ /\//){
  if ($path =~ /^\//){
    $path =~ /^((\/[^\/]+){1,}\/)[^\/]+$/;
    $path = $1;
    }
  else {
    $path =~ /^(([^\/]+\/){1,})[^\/]+$/;
    my $path_b = $1;
    my $path_a = `pwd`;
    chop($path_a);
    $path = $path_a."/".$path_b;
    }
  }
else{
  $path = `pwd`;
  chop($path);
  $path.="/";
  }
$path =~ s/\/\//\//g;



print "\n$path\n";

:DD Share Improve this answer Follow answered Nov 26 '12 at 14:01 mkc 11 1 1 bronze badge

Lee Taylor ,

Please don't just answer with code. Please explain why this is the correct answer. – Lee Taylor Nov 26 '12 at 14:21

Yong Li , 2011-04-01 16:27:08

1

Are you looking for this?:

my $thisfile = $1 if $0 =~
/\\([^\\]*)$|\/([^\/]*)$/;

print "You are running $thisfile
now.\n";

The output will look like this:

You are running MyFileName.pl now.

It works on both Windows and Unix. Share Improve this answer Follow edited Aug 19 '13 at 21:29 the Tin Man 151k 39 39 gold badges 197 197 silver badges 279 279 bronze badges answered Apr 1 '11 at 16:27 Yong Li 11 1 1 bronze badge

> ,

Add a comment

Yordan Georgiev , 2011-08-09 13:36:04

0
use strict ; use warnings ; use Cwd 'abs_path';
    sub ResolveMyProductBaseDir { 

        # Start - Resolve the ProductBaseDir
        #resolve the run dir where this scripts is placed
        my $ScriptAbsolutPath = abs_path($0) ; 
        #debug print "\$ScriptAbsolutPath is $ScriptAbsolutPath \n" ;
        $ScriptAbsolutPath =~ m/^(.*)(\\|\/)(.*)\.([a-z]*)/; 
        $RunDir = $1 ; 
        #debug print "\$1 is $1 \n" ;
        #change the \'s to /'s if we are on Windows
        $RunDir =~s/\\/\//gi ; 
        my @DirParts = split ('/' , $RunDir) ; 
        for (my $count=0; $count < 4; $count++) {   pop @DirParts ;     }
        my $ProductBaseDir = join ( '/' , @DirParts ) ; 
        # Stop - Resolve the ProductBaseDir
        #debug print "ResolveMyProductBaseDir $ProductBaseDir is $ProductBaseDir \n" ; 
        return $ProductBaseDir ; 
    } #eof sub
Share Improve this answer Follow answered Aug 9 '11 at 13:36 Yordan Georgiev 3,986 1 1 gold badge 42 42 silver badges 47 47 bronze badges

the Tin Man ,

While a source-only answer might solve the user's question, it doesn't help them understand why it works. You've given the user a fish, but instead you should teach them HOW to fish. – the Tin Man Aug 19 '13 at 21:28

Jonathan ,

0

The problem with __FILE__ is that it will print the core module ".pm" path not necessarily the ".cgi" or ".pl" script path that is running. I guess it depends on what your goal is.

It seems to me that Cwd just needs to be updated for mod_perl. Here is my suggestion:

my $path;

use File::Basename;
my $file = basename($ENV{SCRIPT_NAME});

if (exists $ENV{MOD_PERL} && ($ENV{MOD_PERL_API_VERSION} < 2)) {
  if ($^O =~/Win/) {
    $path = `echo %cd%`;
    chop $path;
    $path =~ s!\\!/!g;
    $path .= $ENV{SCRIPT_NAME};
  }
  else {
    $path = `pwd`;
    $path .= "/$file";
  }
  # add support for other operating systems
}
else {
  require Cwd;
  $path = Cwd::getcwd()."/$file";
}
print $path;

Please add any suggestions. Share Improve this answer Follow edited Dec 14 '13 at 0:29 answered Dec 13 '13 at 11:57 Jonathan 1,291 2 2 gold badges 19 19 silver badges 40 40 bronze badges

> ,

Add a comment

Putnik ,

0

Without any external modules, valid for shell, works well even with '../':

my $self = `pwd`;
chomp $self;
$self .='/'.$1 if $0 =~/([^\/]*)$/; #keep the filename only
print "self=$self\n";

test:

$ /my/temp/Host$ perl ./host-mod.pl 
self=/my/temp/Host/host-mod.pl

$ /my/temp/Host$ ./host-mod.pl 
self=/my/temp/Host/host-mod.pl

$ /my/temp/Host$ ../Host/./host-mod.pl 
self=/my/temp/Host/host-mod.pl
Share Improve this answer Follow answered Feb 6 '14 at 14:39 Putnik 3,538 4 4 gold badges 26 26 silver badges 43 43 bronze badges

Znik ,

What when you call symlink? Cwd works excellent with this case. – Znik Mar 3 '14 at 12:32

DavidG ,

0

The problem with just using dirname(__FILE__) is that it doesn't follow symlinks. I had to use this for my script to follow the symlink to the actual file location.

use File::Basename;
my $script_dir = undef;
if(-l __FILE__) {
  $script_dir = dirname(readlink(__FILE__));
}
else {
  $script_dir = dirname(__FILE__);
}
Share Improve this answer Follow answered Apr 18 '14 at 7:56 DavidG 3,113 2 2 gold badges 25 25 silver badges 41 41 bronze badges

> ,

Add a comment

Elmar , 2014-09-04 10:32:56

0

All the library-free solutions don't actually work for more than a few ways to write a path (think ../ or /bla/x/../bin/./x/../ etc. My solution looks like below. I have one quirk: I don't have the faintest idea why I have to run the replacements twice. If I don't, I get a spurious "./" or "../". Apart from that, it seems quite robust to me.

  my $callpath = $0;
  my $pwd = `pwd`; chomp($pwd);

  # if called relative -> add pwd in front
  if ($callpath !~ /^\//) { $callpath = $pwd."/".$callpath; }  

  # do the cleanup
  $callpath =~ s!^\./!!;                          # starts with ./ -> drop
  $callpath =~ s!/\./!/!g;                        # /./ -> /
  $callpath =~ s!/\./!/!g;                        # /./ -> /        (twice)

  $callpath =~ s!/[^/]+/\.\./!/!g;                # /xxx/../ -> /
  $callpath =~ s!/[^/]+/\.\./!/!g;                # /xxx/../ -> /   (twice)

  my $calldir = $callpath;
  $calldir =~ s/(.*)\/([^\/]+)/$1/;
Share Improve this answer Follow answered Sep 4 '14 at 10:32 Elmar 1

> ,

Add a comment

drjumper , 2018-10-23 08:51:38

0

None of the "top" answers were right for me. The problem with using FindBin '$Bin' or Cwd is that they return absolute path with all symbolic links resolved. In my case I needed the exact path with symbolic links present - the same as returns Unix command "pwd" and not "pwd -P". The following function provides the solution:

sub get_script_full_path {
    use File::Basename;
    use File::Spec;
    use Cwd qw(chdir cwd);
    my $curr_dir = cwd();
    chdir(dirname($0));
    my $dir = $ENV{PWD};
    chdir( $curr_dir);
    return File::Spec->catfile($dir, basename($0));
}
Share Improve this answer Follow answered Oct 23 '18 at 8:51 drjumper 71 3 3 bronze badges

> ,

Add a comment

user3228609 , 2019-10-16 15:39:42

0

On Windows using dirname and abs_path together worked best for me.

use File::Basename;
use Cwd qw(abs_path);

# absolute path of the directory containing the executing script
my $abs_dirname = dirname(abs_path($0));
print "\ndirname(abs_path(\$0)) -> $abs_dirname\n";

here's why:

# this gives the answer I want in relative path form, not absolute
my $rel_dirname = dirname(__FILE__); 
print "dirname(__FILE__) -> $rel_dirname\n"; 

# this gives the slightly wrong answer, but in the form I want 
my $full_filepath = abs_path($0);
print "abs_path(\$0) -> $full_filepath\n";
Share Improve this answer Follow edited Oct 16 '19 at 16:01 answered Oct 16 '19 at 15:39 user3228609 1 1 1 bronze badge

> ,

Add a comment

user3673 , 2020-08-23 17:39:37

0
use File::Basename;
use Cwd 'abs_path';
print dirname(abs_path(__FILE__)) ;

Drew's answer gave me:

'.'

$ cat >testdirname
use File::Basename;
print dirname(__FILE__);
$ perl testdirname
.$ perl -v

This is perl 5, version 28, subversion 1 (v5.28.1) built for x86_64-linux-gnu-thread-multi][1]
Share Improve this answer Follow answered Aug 23 '20 at 17:39 user3673 496 3 3 silver badges 17 17 bronze badges

> ,

Add a comment

user3061015 ,

-2

What's wrong with $^X ?

#!/usr/bin/env perl<br>
print "This is executed by $^X\n";

Would give you the full path to the Perl binary being used.

Evert Share Improve this answer Follow edited Dec 3 '13 at 11:06 Eugene Loy 11.6k 8 8 gold badges 47 47 silver badges 73 73 bronze badges answered Dec 3 '13 at 10:48 user3061015 1 2 2 bronze badges

Putnik ,

It gives path to the Perl binary whilst path to a script required – Putnik Feb 6 '14 at 14:00

[Oct 10, 2020] Doesn't Perl include current directory in @INC by default?

Jan 01, 2017 | stackoverflow.com

Ask Question Asked 3 years ago Active 2 years ago Viewed 6k times

https://tpc.googlesyndication.com/safeframe/1-0-37/html/container.html Report this ad


Stephen , 2017-10-03 16:52:57

17 7

I have never fully understood Perl's resolution of package names, but I always assumed that the following should always work, assuming you are executing myscript.pl from within the directory that contains it:

myscript.pl (contains the following statement: use Class1::Class2::Class3)
Class1/
    Class2/
        Class3.pm (contains the following package declaration: package Class1::Class2::Class3;)

However, this is not working in my code because Class3.pm cannot be located. Looking at @INC, it does not include the current directory, only various directories of my Strawberry Perl installation.

What is the recommended way to solve this? I suppose I could modify @INC, or I could start using FindBin, but I'm not sure which is best. I have inherited this code and am simply migrating it to a new location, but it doesn't look like the old code needed either such solution (I could be wrong, still looking...) perl share edit follow edited Nov 21 '17 at 15:50 ikegami 308k 14 14 gold badges 213 213 silver badges 452 452 bronze badges asked Oct 3 '17 at 16:52 Stephen 5,308 5 5 gold badges 34 34 silver badges 66 66 bronze badges

> ,

add a comment 3 Answers Active Oldest Votes

ikegami ,

30

Perl doesn't search the current directory for modules or the script's directory for modules, at least not anymore. The current directory was removed from @INC in 5.26 for security reasons.

However, any code that relies on the current directory being in @INC was buggy far before 5.26. Code that did so, like yours, incorrectly used the current directory as a proxy for the script's directory. That assumption is often incorrect.

To tell Perl to look in the script's directory for modules, use the following:

use FindBin 1.51 qw( $RealBin );
use lib $RealBin;

or

use Cwd qw( abs_path );
use File::Basename qw( dirname );
use lib dirname(abs_path($0));
share edit follow edited Oct 4 '18 at 8:27 answered Oct 3 '17 at 17:39 ikegami 308k 14 14 gold badges 213 213 silver badges 452 452 bronze badges

ikegami ,

A tangential question, but why $RealBin and not just $Bin ? Does having the links resolved give us any benefit here, or have you used it here just a general good practice? – sundar - Reinstate Monica Apr 9 '18 at 12:19

melpomene , 2017-10-03 17:00:02

9

Having . (the current directory) in @INC was removed in 5.26 for security reasons ( CVE-2016-1238 ). Some Linux distributions have backported the change, so you might run into this problem even if you're using e.g. 5.24. share edit follow edited Oct 3 '17 at 17:44 answered Oct 3 '17 at 17:00 melpomene 77.6k 6 6 gold badges 63 63 silver badges 117 117 bronze badges

melpomene ,

@ikegami Oh, interesting. I didn't know FindBin was fixed. It did search $PATH until version 1.51, released with perl 5.16. – melpomene Oct 3 '17 at 17:42

> ,

7

Perl 5.26 removed having the current working directory in @INC as a security measure.

It's explained in the 5.26 perldelta notes .

[Oct 09, 2020] Doesn't Perl include current directory in @INC by default?

Jan 01, 2017 | stackoverflow.com

Ask Question Asked 3 years ago Active 2 years ago Viewed 6k times

https://tpc.googlesyndication.com/safeframe/1-0-37/html/container.html Report this ad


Stephen , 2017-10-03 16:52:57

17 7

I have never fully understood Perl's resolution of package names, but I always assumed that the following should always work, assuming you are executing myscript.pl from within the directory that contains it:

myscript.pl (contains the following statement: use Class1::Class2::Class3)
Class1/
    Class2/
        Class3.pm (contains the following package declaration: package Class1::Class2::Class3;)

However, this is not working in my code because Class3.pm cannot be located. Looking at @INC, it does not include the current directory, only various directories of my Strawberry Perl installation.

What is the recommended way to solve this? I suppose I could modify @INC, or I could start using FindBin, but I'm not sure which is best. I have inherited this code and am simply migrating it to a new location, but it doesn't look like the old code needed either such solution (I could be wrong, still looking...) perl share edit follow edited Nov 21 '17 at 15:50 ikegami 308k 14 14 gold badges 213 213 silver badges 452 452 bronze badges asked Oct 3 '17 at 16:52 Stephen 5,308 5 5 gold badges 34 34 silver badges 66 66 bronze badges

> ,

add a comment 3 Answers Active Oldest Votes

ikegami ,

30

Perl doesn't search the current directory for modules or the script's directory for modules, at least not anymore. The current directory was removed from @INC in 5.26 for security reasons.

However, any code that relies on the current directory being in @INC was buggy far before 5.26. Code that did so, like yours, incorrectly used the current directory as a proxy for the script's directory. That assumption is often incorrect.

To tell Perl to look in the script's directory for modules, use the following:

use FindBin 1.51 qw( $RealBin );
use lib $RealBin;

or

use Cwd qw( abs_path );
use File::Basename qw( dirname );
use lib dirname(abs_path($0));
share edit follow edited Oct 4 '18 at 8:27 answered Oct 3 '17 at 17:39 ikegami 308k 14 14 gold badges 213 213 silver badges 452 452 bronze badges

ikegami ,

A tangential question, but why $RealBin and not just $Bin ? Does having the links resolved give us any benefit here, or have you used it here just a general good practice? – sundar - Reinstate Monica Apr 9 '18 at 12:19

melpomene , 2017-10-03 17:00:02

9

Having . (the current directory) in @INC was removed in 5.26 for security reasons ( CVE-2016-1238 ). Some Linux distributions have backported the change, so you might run into this problem even if you're using e.g. 5.24. share edit follow edited Oct 3 '17 at 17:44 answered Oct 3 '17 at 17:00 melpomene 77.6k 6 6 gold badges 63 63 silver badges 117 117 bronze badges

melpomene ,

@ikegami Oh, interesting. I didn't know FindBin was fixed. It did search $PATH until version 1.51, released with perl 5.16. – melpomene Oct 3 '17 at 17:42

> ,

7

Perl 5.26 removed having the current working directory in @INC as a security measure.

It's explained in the 5.26 perldelta notes .

[Oct 03, 2020] Setting PERL5LIB

Jan 01, 2011 | stackoverflow.com

Asked 9 years, 7 months ago


CMS , 2011-03-02 12:31:46

9 1

Can I set PERL5LIB in a separate script and call that script in other scripts? How do I do it? And how would it affect the script in which it is used?

Thanks. perl share improve this question follow asked Mar 2 '11 at 12:31 CMS 113 1 1 gold badge 1 1 silver badge 6 6 bronze badges

add a comment 5 Answers Active Oldest Votes

Eugene Yarmash ,

7

Setting PERL5LIB at runtime will not affect Perl's search path. You need to export the variable before executing the interpreter.
Alternatively you can modify @INC at compile time (also possible to do in a separate script/module):

BEGIN { unshift @INC, "/path/to/dir" }

This is what the lib pragma does. share improve this answer follow edited Mar 2 '11 at 14:35 answered Mar 2 '11 at 12:55 Eugene Yarmash 112k 29 29 gold badges 251 251 silver badges 316 316 bronze badges

Mark ,

This doesn't work for me, I think because the PERL5LIB environment variable is processed by the interpreter before the script is executed, so @INC isn't modified. – Mark Mar 2 '11 at 13:25

Mark , 2011-03-02 13:11:54

4

You'd do this via 'use lib' rather than manipulating the environment:

use lib '/home/perl5';

That could be in a separate file that you 'require' in. share improve this answer follow edited Mar 2 '11 at 13:24 answered Mar 2 '11 at 13:11 Mark 431 3 3 silver badges 6 6 bronze badges

> ,

add a comment

zrajm , 2014-05-20 11:05:43

1

PERL5INC is a shell environment variable, so you wouldn't set it inside your Perl program (normally) but instead specify it before invoking Perl. The below is a shell command where I've used PERL5LIB to instruct prove to find a Perl module residing in ~/OnePop :

$ PERL5LIB=~/OnePop prove -l t
... PERL5LIB is unset here ....

When a command is preceded by a variable assignment like this, the shell sets and exports the variable ( PERL5LIB ) to that command, but after that the variable will be unset again. You can also set the variable in the shell, so that all subsequent commands will inherit it.

$ export PERL5LIB=~/OnePop
...
$ prove -l t
... PERL5LIB continues to be set here ...

If you forget the export keyword in the above example (i.e. assigns the value using PERL5LIB=~/OnePop on a separate line) the variable will be set in the shell, but it will not be inherited by any commands you run (meaning that prove will not be able to see it).

Finally, if you wanted to set the environment PERL5LIB variable from inside a Perl program you'd have to write it like this:

$ENV{PERL5LIB} = glob("~/OnePop");   # glob() expands the tilde
system(qw( prove -l t ));

Though, as other have pointed out, if you want to specify the include path from inside Perl it is easier/better to use use lib $PATH . share improve this answer follow answered May 20 '14 at 11:05 zrajm 1,149 1 1 gold badge 11 11 silver badges 18 18 bronze badges

> ,

add a comment

bot403 , 2011-03-02 14:44:36

0

PERL5INC is an environment variable. Environment variables are only inherited from parents to their children and can't (easily) be set the other way around. If you want to store extra search paths in an external file I suggest you make it a simple list of paths and write a simple loop to read each path from the file and manipulate @INC in the current process. If you want this to be done early at compile time you'll have to use a BEGIN {} block.

For example

BEGIN{
  open(INCFILE,"<","my.inc.file") or die($!);
  foreach(<INCFILE>){
    push @INC,$_;
  }
  close(INCFILE);
}
share improve this answer follow edited Mar 27 '17 at 11:00 Donal Fellows 115k 17 17 gold badges 126 126 silver badges 190 190 bronze badges answered Mar 2 '11 at 14:44 bot403 1,923 13 13 silver badges 14 14 bronze badges

> ,

add a comment

> ,

0 Alternative to PERL5LIB:

You could instead install the latest version of Perl 5 available (in a non-system location, of course). After you have used a module file or done whatever is necessary to make the new perl and cpan executables visible to your shell, you can use cpan to install all the modules you need. I have sometimes done this for individual applications in a similar vein to using Python Virtual Environments.

[Dec 01, 2019] How can I export all subs in a Perl package?

Jan 01, 2009 | stackoverflow.com

Ask Question Asked 10 years, 7 months ago Active 3 years, 5 months ago Viewed 18k times


Ville M ,

I would like to expose all subs into my namespace without having to list them one at a time:
@EXPORT = qw( firstsub secondsub third sub etc );

Using fully qualified names would require bunch of change to existing code so I'd rather not do that.

Is there @EXPORT_ALL?

I think documentation says it's a bad idea, but I'd like to do it anyway, or at least know how.

To answer Jon's why: right now for quick refactoring I want to move of bunch of subs into their own package with least hassle and code changes to the existing scripts (where those subs are currenty used and often repeated).

Also, mostly, I was just curious. (since it seemed like that Exporter might as well have that as standard feature, but somewhat surprisingly based on answers so far it doesn't)

brian d foy , 2009-04-08 23:58:35

Don't do any exporting at all, and don't declare a package name in your library. Just load the file with require and everything will be in the current package. Easy peasy.

Michael Carman , 2009-04-09 00:15:10

Don't. But if you really want to... write a custom import that walks the symbol table and export all the named subroutines.
# Export all subs in package. Not for use in production code!
sub import {
    no strict 'refs';

    my $caller = caller;

    while (my ($name, $symbol) = each %{__PACKAGE__ . '::'}) {
        next if      $name eq 'BEGIN';   # don't export BEGIN blocks
        next if      $name eq 'import';  # don't export this sub
        next unless *{$symbol}{CODE};    # export subs only

        my $imported = $caller . '::' . $name;
        *{ $imported } = \*{ $symbol };
    }
}

Chas. Owens ,

Warning, the code following is as bad an idea as exporting everything:
package Expo;

use base "Exporter";

seek DATA, 0, 0; #move DATA back to package

#read this file looking for sub names
our @EXPORT = map { /^sub\s+([^({\s]+)/ ? $1 : () } <DATA>;

my $sub = sub {}; #make sure anon funcs aren't grabbed

sub foo($) {
    print shift, "\n";
}

sub bar ($) {
    print shift, "\n";
}

sub baz{
    print shift,"\n";
}

sub quux {
    print shift,"\n";
}

1;

__DATA__

Here is the some code that uses the module:

#!/usr/bin/perl

use strict;
use warnings;

use Expo;

print map { "[$_]\n" } @Expo::EXPORT;

foo("foo");
bar("bar");
baz("baz");
quux("quux");

And here is its output:

[foo]
[bar]
[baz]
[quux]
foo
bar
baz
quux

Jon Ericson , 2009-04-08 22:33:36

You can always call subroutines in there fully-specified form:
MyModule::firstsub();

For modules I write internally, I find this convention works fairly well. It's a bit more typing, but tends to be better documentation.

Take a look at perldoc perlmod for more information about what you are trying to accomplish.

More generally, you could look at Exporter 's code and see how it uses glob aliasing. Or you can examine your module's namespace and export each subroutine. (I don't care to search for how to do that at the moment, but Perl makes this fairly easy.) Or you could just stick your subroutines in the main package:

 package main;
 sub firstsub() { ... }

(I don't think that's a good idea, but you know better than I do what you are trying to accomplish.)

There's nothing wrong with doing this provided you know what you are doing and aren't just trying to avoid thinking about your interface to the outside world.

ysth , 2009-04-09 01:29:04

Perhaps you would be interested in one of the Export* modules on CPAN that lets you mark subs as exportable simply by adding an attribute to the sub definition? (Don't remember which one it was, though.)

echo , 2014-10-11 18:23:01

https://metacpan.org/pod/Exporter::Auto

Exporter::Auto. this is all you need.

Tero Niemi , 2013-04-02 00:32:25

Although it is not usually wise to dump all sub s from module into the caller namespace, it is sometimes useful (and more DRY!) to automatically generate @EXPORT_OK and %EXPORT_TAGS variables.

The easiest method is to extend the Exporter. A simple example is something like this:

package Exporter::AutoOkay;
#
#   Automatically add all subroutines from caller package into the
#   @EXPORT_OK array. In the package use like Exporter, f.ex.:
#
#       use parent 'Exporter::AutoOkay';
#
use warnings;
use strict;
no strict 'refs';

require Exporter;

sub import {
    my $package = $_[0].'::';

    # Get the list of exportable items
    my @export_ok = (@{$package.'EXPORT_OK'});

    # Automatically add all subroutines from package into the list
    foreach (keys %{$package}) {
        next unless defined &{$package.$_};
        push @export_ok, $_;
    }

    # Set variable ready for Exporter
    @{$package.'EXPORT_OK'} = @export_ok;

    # Let Exporter do the rest
    goto &Exporter::import;
}

1;

Note the use of goto that removes us from the caller stack.

A more complete example can be found here: http://pastebin.com/Z1QWzcpZ It automatically generates tag groups from subroutine prefixes.

Sérgio , 2013-11-14 21:38:06

case 1

Library is :

package mycommon;

use strict;
use warnings;

sub onefunctionthatyoumadeonlibary() {
}
1;

you can use it, calling common:: :

#!/usr/bin/perl
use strict;
use warnings;
use mycommon;

common::onefunctionthatyoumadeonlibary()
case 2

Library is , yousimple export them :

package mycommon;

use strict;
use warnings;

use base 'Exporter';

our @EXPORT = qw(onefunctionthatyoumadeonlibary);
sub onefunctionthatyoumadeonlibary() {
}
1;

use it in same "namespace":

#!/usr/bin/perl
use strict;
use warnings;
use mycommon qw(onefunctionthatyoumadeonlibary);

onefunctionthatyoumadeonlibary()

Also we can do a mix of this two cases , we can export more common functions to use it without calling the packages name and other functions that we only call it with package name and that ones don't need to be exported.

> ,

You will have to do some typeglob munging. I describe something similar here:

Is there a way to "use" a single file that in turn uses multiple others in Perl?

The import routine there should do exactly what you want -- just don't import any symbols into your own namespace.

Ville M ,

I would like to expose all subs into my namespace without having to list them one at a time:
@EXPORT = qw( firstsub secondsub third sub etc );

Using fully qualified names would require bunch of change to existing code so I'd rather not do that.

Is there @EXPORT_ALL?

I think documentation says it's a bad idea, but I'd like to do it anyway, or at least know how.

To answer Jon's why: right now for quick refactoring I want to move of bunch of subs into their own package with least hassle and code changes to the existing scripts (where those subs are currenty used and often repeated).

Also, mostly, I was just curious. (since it seemed like that Exporter might as well have that as standard feature, but somewhat surprisingly based on answers so far it doesn't)

brian d foy , 2009-04-08 23:58:35

Don't do any exporting at all, and don't declare a package name in your library. Just load the file with require and everything will be in the current package. Easy peasy.

Michael Carman , 2009-04-09 00:15:10

Don't. But if you really want to... write a custom import that walks the symbol table and export all the named subroutines.
# Export all subs in package. Not for use in production code!
sub import {
    no strict 'refs';

    my $caller = caller;

    while (my ($name, $symbol) = each %{__PACKAGE__ . '::'}) {
        next if      $name eq 'BEGIN';   # don't export BEGIN blocks
        next if      $name eq 'import';  # don't export this sub
        next unless *{$symbol}{CODE};    # export subs only

        my $imported = $caller . '::' . $name;
        *{ $imported } = \*{ $symbol };
    }
}

Chas. Owens ,

Warning, the code following is as bad an idea as exporting everything:
package Expo;

use base "Exporter";

seek DATA, 0, 0; #move DATA back to package

#read this file looking for sub names
our @EXPORT = map { /^sub\s+([^({\s]+)/ ? $1 : () } <DATA>;

my $sub = sub {}; #make sure anon funcs aren't grabbed

sub foo($) {
    print shift, "\n";
}

sub bar ($) {
    print shift, "\n";
}

sub baz{
    print shift,"\n";
}

sub quux {
    print shift,"\n";
}

1;

__DATA__

Here is the some code that uses the module:

#!/usr/bin/perl

use strict;
use warnings;

use Expo;

print map { "[$_]\n" } @Expo::EXPORT;

foo("foo");
bar("bar");
baz("baz");
quux("quux");

And here is its output:

[foo]
[bar]
[baz]
[quux]
foo
bar
baz
quux

Jon Ericson , 2009-04-08 22:33:36

You can always call subroutines in there fully-specified form:
MyModule::firstsub();

For modules I write internally, I find this convention works fairly well. It's a bit more typing, but tends to be better documentation.

Take a look at perldoc perlmod for more information about what you are trying to accomplish.

More generally, you could look at Exporter 's code and see how it uses glob aliasing. Or you can examine your module's namespace and export each subroutine. (I don't care to search for how to do that at the moment, but Perl makes this fairly easy.) Or you could just stick your subroutines in the main package:

 package main;
 sub firstsub() { ... }

(I don't think that's a good idea, but you know better than I do what you are trying to accomplish.)

There's nothing wrong with doing this provided you know what you are doing and aren't just trying to avoid thinking about your interface to the outside world.

ysth , 2009-04-09 01:29:04

Perhaps you would be interested in one of the Export* modules on CPAN that lets you mark subs as exportable simply by adding an attribute to the sub definition? (Don't remember which one it was, though.)

echo , 2014-10-11 18:23:01

https://metacpan.org/pod/Exporter::Auto

Exporter::Auto. this is all you need.

Tero Niemi , 2013-04-02 00:32:25

Although it is not usually wise to dump all sub s from module into the caller namespace, it is sometimes useful (and more DRY!) to automatically generate @EXPORT_OK and %EXPORT_TAGS variables.

The easiest method is to extend the Exporter. A simple example is something like this:

package Exporter::AutoOkay;
#
#   Automatically add all subroutines from caller package into the
#   @EXPORT_OK array. In the package use like Exporter, f.ex.:
#
#       use parent 'Exporter::AutoOkay';
#
use warnings;
use strict;
no strict 'refs';

require Exporter;

sub import {
    my $package = $_[0].'::';

    # Get the list of exportable items
    my @export_ok = (@{$package.'EXPORT_OK'});

    # Automatically add all subroutines from package into the list
    foreach (keys %{$package}) {
        next unless defined &{$package.$_};
        push @export_ok, $_;
    }

    # Set variable ready for Exporter
    @{$package.'EXPORT_OK'} = @export_ok;

    # Let Exporter do the rest
    goto &Exporter::import;
}

1;

Note the use of goto that removes us from the caller stack.

A more complete example can be found here: http://pastebin.com/Z1QWzcpZ It automatically generates tag groups from subroutine prefixes.

Sérgio , 2013-11-14 21:38:06

case 1

Library is :

package mycommon;

use strict;
use warnings;

sub onefunctionthatyoumadeonlibary() {
}
1;

you can use it, calling common:: :

#!/usr/bin/perl
use strict;
use warnings;
use mycommon;

common::onefunctionthatyoumadeonlibary()
case 2

Library is , yousimple export them :

package mycommon;

use strict;
use warnings;

use base 'Exporter';

our @EXPORT = qw(onefunctionthatyoumadeonlibary);
sub onefunctionthatyoumadeonlibary() {
}
1;

use it in same "namespace":

#!/usr/bin/perl
use strict;
use warnings;
use mycommon qw(onefunctionthatyoumadeonlibary);

onefunctionthatyoumadeonlibary()

Also we can do a mix of this two cases , we can export more common functions to use it without calling the packages name and other functions that we only call it with package name and that ones don't need to be exported.

> ,

You will have to do some typeglob munging. I describe something similar here:

Is there a way to "use" a single file that in turn uses multiple others in Perl?

The import routine there should do exactly what you want -- just don't import any symbols into your own namespace.

Ville M ,

I would like to expose all subs into my namespace without having to list them one at a time:
@EXPORT = qw( firstsub secondsub third sub etc );

Using fully qualified names would require bunch of change to existing code so I'd rather not do that.

Is there @EXPORT_ALL?

I think documentation says it's a bad idea, but I'd like to do it anyway, or at least know how.

To answer Jon's why: right now for quick refactoring I want to move of bunch of subs into their own package with least hassle and code changes to the existing scripts (where those subs are currenty used and often repeated).

Also, mostly, I was just curious. (since it seemed like that Exporter might as well have that as standard feature, but somewhat surprisingly based on answers so far it doesn't)

brian d foy , 2009-04-08 23:58:35

Don't do any exporting at all, and don't declare a package name in your library. Just load the file with require and everything will be in the current package. Easy peasy.

Michael Carman , 2009-04-09 00:15:10

Don't. But if you really want to... write a custom import that walks the symbol table and export all the named subroutines.
# Export all subs in package. Not for use in production code!
sub import {
    no strict 'refs';

    my $caller = caller;

    while (my ($name, $symbol) = each %{__PACKAGE__ . '::'}) {
        next if      $name eq 'BEGIN';   # don't export BEGIN blocks
        next if      $name eq 'import';  # don't export this sub
        next unless *{$symbol}{CODE};    # export subs only

        my $imported = $caller . '::' . $name;
        *{ $imported } = \*{ $symbol };
    }
}

Chas. Owens ,

Warning, the code following is as bad an idea as exporting everything:
package Expo;

use base "Exporter";

seek DATA, 0, 0; #move DATA back to package

#read this file looking for sub names
our @EXPORT = map { /^sub\s+([^({\s]+)/ ? $1 : () } <DATA>;

my $sub = sub {}; #make sure anon funcs aren't grabbed

sub foo($) {
    print shift, "\n";
}

sub bar ($) {
    print shift, "\n";
}

sub baz{
    print shift,"\n";
}

sub quux {
    print shift,"\n";
}

1;

__DATA__

Here is the some code that uses the module:

#!/usr/bin/perl

use strict;
use warnings;

use Expo;

print map { "[$_]\n" } @Expo::EXPORT;

foo("foo");
bar("bar");
baz("baz");
quux("quux");

And here is its output:

[foo]
[bar]
[baz]
[quux]
foo
bar
baz
quux

Jon Ericson , 2009-04-08 22:33:36

You can always call subroutines in there fully-specified form:
MyModule::firstsub();

For modules I write internally, I find this convention works fairly well. It's a bit more typing, but tends to be better documentation.

Take a look at perldoc perlmod for more information about what you are trying to accomplish.

More generally, you could look at Exporter 's code and see how it uses glob aliasing. Or you can examine your module's namespace and export each subroutine. (I don't care to search for how to do that at the moment, but Perl makes this fairly easy.) Or you could just stick your subroutines in the main package:

 package main;
 sub firstsub() { ... }

(I don't think that's a good idea, but you know better than I do what you are trying to accomplish.)

There's nothing wrong with doing this provided you know what you are doing and aren't just trying to avoid thinking about your interface to the outside world.

ysth , 2009-04-09 01:29:04

Perhaps you would be interested in one of the Export* modules on CPAN that lets you mark subs as exportable simply by adding an attribute to the sub definition? (Don't remember which one it was, though.)

echo , 2014-10-11 18:23:01

https://metacpan.org/pod/Exporter::Auto

Exporter::Auto. this is all you need.

Tero Niemi , 2013-04-02 00:32:25

Although it is not usually wise to dump all sub s from module into the caller namespace, it is sometimes useful (and more DRY!) to automatically generate @EXPORT_OK and %EXPORT_TAGS variables.

The easiest method is to extend the Exporter. A simple example is something like this:

package Exporter::AutoOkay;
#
#   Automatically add all subroutines from caller package into the
#   @EXPORT_OK array. In the package use like Exporter, f.ex.:
#
#       use parent 'Exporter::AutoOkay';
#
use warnings;
use strict;
no strict 'refs';

require Exporter;

sub import {
    my $package = $_[0].'::';

    # Get the list of exportable items
    my @export_ok = (@{$package.'EXPORT_OK'});

    # Automatically add all subroutines from package into the list
    foreach (keys %{$package}) {
        next unless defined &{$package.$_};
        push @export_ok, $_;
    }

    # Set variable ready for Exporter
    @{$package.'EXPORT_OK'} = @export_ok;

    # Let Exporter do the rest
    goto &Exporter::import;
}

1;

Note the use of goto that removes us from the caller stack.

A more complete example can be found here: http://pastebin.com/Z1QWzcpZ It automatically generates tag groups from subroutine prefixes.

Sérgio , 2013-11-14 21:38:06

case 1

Library is :

package mycommon;

use strict;
use warnings;

sub onefunctionthatyoumadeonlibary() {
}
1;

you can use it, calling common:: :

#!/usr/bin/perl
use strict;
use warnings;
use mycommon;

common::onefunctionthatyoumadeonlibary()
case 2

Library is , yousimple export them :

package mycommon;

use strict;
use warnings;

use base 'Exporter';

our @EXPORT = qw(onefunctionthatyoumadeonlibary);
sub onefunctionthatyoumadeonlibary() {
}
1;

use it in same "namespace":

#!/usr/bin/perl
use strict;
use warnings;
use mycommon qw(onefunctionthatyoumadeonlibary);

onefunctionthatyoumadeonlibary()

Also we can do a mix of this two cases , we can export more common functions to use it without calling the packages name and other functions that we only call it with package name and that ones don't need to be exported.

> ,

You will have to do some typeglob munging. I describe something similar here:

Is there a way to "use" a single file that in turn uses multiple others in Perl?

The import routine there should do exactly what you want -- just don't import any symbols into your own namespace.

Ville M ,

I would like to expose all subs into my namespace without having to list them one at a time:
@EXPORT = qw( firstsub secondsub third sub etc );

Using fully qualified names would require bunch of change to existing code so I'd rather not do that.

Is there @EXPORT_ALL?

I think documentation says it's a bad idea, but I'd like to do it anyway, or at least know how.

To answer Jon's why: right now for quick refactoring I want to move of bunch of subs into their own package with least hassle and code changes to the existing scripts (where those subs are currenty used and often repeated).

Also, mostly, I was just curious. (since it seemed like that Exporter might as well have that as standard feature, but somewhat surprisingly based on answers so far it doesn't)

brian d foy , 2009-04-08 23:58:35

Don't do any exporting at all, and don't declare a package name in your library. Just load the file with require and everything will be in the current package. Easy peasy.

Michael Carman , 2009-04-09 00:15:10

Don't. But if you really want to... write a custom import that walks the symbol table and export all the named subroutines.
# Export all subs in package. Not for use in production code!
sub import {
    no strict 'refs';

    my $caller = caller;

    while (my ($name, $symbol) = each %{__PACKAGE__ . '::'}) {
        next if      $name eq 'BEGIN';   # don't export BEGIN blocks
        next if      $name eq 'import';  # don't export this sub
        next unless *{$symbol}{CODE};    # export subs only

        my $imported = $caller . '::' . $name;
        *{ $imported } = \*{ $symbol };
    }
}

Chas. Owens ,

Warning, the code following is as bad an idea as exporting everything:
package Expo;

use base "Exporter";

seek DATA, 0, 0; #move DATA back to package

#read this file looking for sub names
our @EXPORT = map { /^sub\s+([^({\s]+)/ ? $1 : () } <DATA>;

my $sub = sub {}; #make sure anon funcs aren't grabbed

sub foo($) {
    print shift, "\n";
}

sub bar ($) {
    print shift, "\n";
}

sub baz{
    print shift,"\n";
}

sub quux {
    print shift,"\n";
}

1;

__DATA__

Here is the some code that uses the module:

#!/usr/bin/perl

use strict;
use warnings;

use Expo;

print map { "[$_]\n" } @Expo::EXPORT;

foo("foo");
bar("bar");
baz("baz");
quux("quux");

And here is its output:

[foo]
[bar]
[baz]
[quux]
foo
bar
baz
quux

Jon Ericson , 2009-04-08 22:33:36

You can always call subroutines in there fully-specified form:
MyModule::firstsub();

For modules I write internally, I find this convention works fairly well. It's a bit more typing, but tends to be better documentation.

Take a look at perldoc perlmod for more information about what you are trying to accomplish.

More generally, you could look at Exporter 's code and see how it uses glob aliasing. Or you can examine your module's namespace and export each subroutine. (I don't care to search for how to do that at the moment, but Perl makes this fairly easy.) Or you could just stick your subroutines in the main package:

 package main;
 sub firstsub() { ... }

(I don't think that's a good idea, but you know better than I do what you are trying to accomplish.)

There's nothing wrong with doing this provided you know what you are doing and aren't just trying to avoid thinking about your interface to the outside world.

ysth , 2009-04-09 01:29:04

Perhaps you would be interested in one of the Export* modules on CPAN that lets you mark subs as exportable simply by adding an attribute to the sub definition? (Don't remember which one it was, though.)

echo , 2014-10-11 18:23:01

https://metacpan.org/pod/Exporter::Auto

Exporter::Auto. this is all you need.

Tero Niemi , 2013-04-02 00:32:25

Although it is not usually wise to dump all sub s from module into the caller namespace, it is sometimes useful (and more DRY!) to automatically generate @EXPORT_OK and %EXPORT_TAGS variables.

The easiest method is to extend the Exporter. A simple example is something like this:

package Exporter::AutoOkay;
#
#   Automatically add all subroutines from caller package into the
#   @EXPORT_OK array. In the package use like Exporter, f.ex.:
#
#       use parent 'Exporter::AutoOkay';
#
use warnings;
use strict;
no strict 'refs';

require Exporter;

sub import {
    my $package = $_[0].'::';

    # Get the list of exportable items
    my @export_ok = (@{$package.'EXPORT_OK'});

    # Automatically add all subroutines from package into the list
    foreach (keys %{$package}) {
        next unless defined &{$package.$_};
        push @export_ok, $_;
    }

    # Set variable ready for Exporter
    @{$package.'EXPORT_OK'} = @export_ok;

    # Let Exporter do the rest
    goto &Exporter::import;
}

1;

Note the use of goto that removes us from the caller stack.

A more complete example can be found here: http://pastebin.com/Z1QWzcpZ It automatically generates tag groups from subroutine prefixes.

Sérgio , 2013-11-14 21:38:06

case 1

Library is :

package mycommon;

use strict;
use warnings;

sub onefunctionthatyoumadeonlibary() {
}
1;

you can use it, calling common:: :

#!/usr/bin/perl
use strict;
use warnings;
use mycommon;

common::onefunctionthatyoumadeonlibary()
case 2

Library is , yousimple export them :

package mycommon;

use strict;
use warnings;

use base 'Exporter';

our @EXPORT = qw(onefunctionthatyoumadeonlibary);
sub onefunctionthatyoumadeonlibary() {
}
1;

use it in same "namespace":

#!/usr/bin/perl
use strict;
use warnings;
use mycommon qw(onefunctionthatyoumadeonlibary);

onefunctionthatyoumadeonlibary()

Also we can do a mix of this two cases , we can export more common functions to use it without calling the packages name and other functions that we only call it with package name and that ones don't need to be exported.

> ,

You will have to do some typeglob munging. I describe something similar here:

Is there a way to "use" a single file that in turn uses multiple others in Perl?

The import routine there should do exactly what you want -- just don't import any symbols into your own namespace.

Ville M ,

I would like to expose all subs into my namespace without having to list them one at a time:
@EXPORT = qw( firstsub secondsub third sub etc );

Using fully qualified names would require bunch of change to existing code so I'd rather not do that.

Is there @EXPORT_ALL?

I think documentation says it's a bad idea, but I'd like to do it anyway, or at least know how.

To answer Jon's why: right now for quick refactoring I want to move of bunch of subs into their own package with least hassle and code changes to the existing scripts (where those subs are currenty used and often repeated).

Also, mostly, I was just curious. (since it seemed like that Exporter might as well have that as standard feature, but somewhat surprisingly based on answers so far it doesn't)

brian d foy , 2009-04-08 23:58:35

Don't do any exporting at all, and don't declare a package name in your library. Just load the file with require and everything will be in the current package. Easy peasy.

Michael Carman , 2009-04-09 00:15:10

Don't. But if you really want to... write a custom import that walks the symbol table and export all the named subroutines.
# Export all subs in package. Not for use in production code!
sub import {
    no strict 'refs';

    my $caller = caller;

    while (my ($name, $symbol) = each %{__PACKAGE__ . '::'}) {
        next if      $name eq 'BEGIN';   # don't export BEGIN blocks
        next if      $name eq 'import';  # don't export this sub
        next unless *{$symbol}{CODE};    # export subs only

        my $imported = $caller . '::' . $name;
        *{ $imported } = \*{ $symbol };
    }
}

Chas. Owens ,

Warning, the code following is as bad an idea as exporting everything:
package Expo;

use base "Exporter";

seek DATA, 0, 0; #move DATA back to package

#read this file looking for sub names
our @EXPORT = map { /^sub\s+([^({\s]+)/ ? $1 : () } <DATA>;

my $sub = sub {}; #make sure anon funcs aren't grabbed

sub foo($) {
    print shift, "\n";
}

sub bar ($) {
    print shift, "\n";
}

sub baz{
    print shift,"\n";
}

sub quux {
    print shift,"\n";
}

1;

__DATA__

Here is the some code that uses the module:

#!/usr/bin/perl

use strict;
use warnings;

use Expo;

print map { "[$_]\n" } @Expo::EXPORT;

foo("foo");
bar("bar");
baz("baz");
quux("quux");

And here is its output:

[foo]
[bar]
[baz]
[quux]
foo
bar
baz
quux

Jon Ericson , 2009-04-08 22:33:36

You can always call subroutines in there fully-specified form:
MyModule::firstsub();

For modules I write internally, I find this convention works fairly well. It's a bit more typing, but tends to be better documentation.

Take a look at perldoc perlmod for more information about what you are trying to accomplish.

More generally, you could look at Exporter 's code and see how it uses glob aliasing. Or you can examine your module's namespace and export each subroutine. (I don't care to search for how to do that at the moment, but Perl makes this fairly easy.) Or you could just stick your subroutines in the main package:

 package main;
 sub firstsub() { ... }

(I don't think that's a good idea, but you know better than I do what you are trying to accomplish.)

There's nothing wrong with doing this provided you know what you are doing and aren't just trying to avoid thinking about your interface to the outside world.

ysth , 2009-04-09 01:29:04

Perhaps you would be interested in one of the Export* modules on CPAN that lets you mark subs as exportable simply by adding an attribute to the sub definition? (Don't remember which one it was, though.)

echo , 2014-10-11 18:23:01

https://metacpan.org/pod/Exporter::Auto

Exporter::Auto. this is all you need.

Tero Niemi , 2013-04-02 00:32:25

Although it is not usually wise to dump all sub s from module into the caller namespace, it is sometimes useful (and more DRY!) to automatically generate @EXPORT_OK and %EXPORT_TAGS variables.

The easiest method is to extend the Exporter. A simple example is something like this:

package Exporter::AutoOkay;
#
#   Automatically add all subroutines from caller package into the
#   @EXPORT_OK array. In the package use like Exporter, f.ex.:
#
#       use parent 'Exporter::AutoOkay';
#
use warnings;
use strict;
no strict 'refs';

require Exporter;

sub import {
    my $package = $_[0].'::';

    # Get the list of exportable items
    my @export_ok = (@{$package.'EXPORT_OK'});

    # Automatically add all subroutines from package into the list
    foreach (keys %{$package}) {
        next unless defined &{$package.$_};
        push @export_ok, $_;
    }

    # Set variable ready for Exporter
    @{$package.'EXPORT_OK'} = @export_ok;

    # Let Exporter do the rest
    goto &Exporter::import;
}

1;

Note the use of goto that removes us from the caller stack.

A more complete example can be found here: http://pastebin.com/Z1QWzcpZ It automatically generates tag groups from subroutine prefixes.

Sérgio , 2013-11-14 21:38:06

case 1

Library is :

package mycommon;

use strict;
use warnings;

sub onefunctionthatyoumadeonlibary() {
}
1;

you can use it, calling common:: :

#!/usr/bin/perl
use strict;
use warnings;
use mycommon;

common::onefunctionthatyoumadeonlibary()
case 2

Library is , yousimple export them :

package mycommon;

use strict;
use warnings;

use base 'Exporter';

our @EXPORT = qw(onefunctionthatyoumadeonlibary);
sub onefunctionthatyoumadeonlibary() {
}
1;

use it in same "namespace":

#!/usr/bin/perl
use strict;
use warnings;
use mycommon qw(onefunctionthatyoumadeonlibary);

onefunctionthatyoumadeonlibary()

Also we can do a mix of this two cases , we can export more common functions to use it without calling the packages name and other functions that we only call it with package name and that ones don't need to be exported.

> ,

You will have to do some typeglob munging. I describe something similar here:

Is there a way to "use" a single file that in turn uses multiple others in Perl?

The import routine there should do exactly what you want -- just don't import any symbols into your own namespace.

Ville M ,

I would like to expose all subs into my namespace without having to list them one at a time:
@EXPORT = qw( firstsub secondsub third sub etc );

Using fully qualified names would require bunch of change to existing code so I'd rather not do that.

Is there @EXPORT_ALL?

I think documentation says it's a bad idea, but I'd like to do it anyway, or at least know how.

To answer Jon's why: right now for quick refactoring I want to move of bunch of subs into their own package with least hassle and code changes to the existing scripts (where those subs are currenty used and often repeated).

Also, mostly, I was just curious. (since it seemed like that Exporter might as well have that as standard feature, but somewhat surprisingly based on answers so far it doesn't)

brian d foy , 2009-04-08 23:58:35

Don't do any exporting at all, and don't declare a package name in your library. Just load the file with require and everything will be in the current package. Easy peasy.

Michael Carman , 2009-04-09 00:15:10

Don't. But if you really want to... write a custom import that walks the symbol table and export all the named subroutines.
# Export all subs in package. Not for use in production code!
sub import {
    no strict 'refs';

    my $caller = caller;

    while (my ($name, $symbol) = each %{__PACKAGE__ . '::'}) {
        next if      $name eq 'BEGIN';   # don't export BEGIN blocks
        next if      $name eq 'import';  # don't export this sub
        next unless *{$symbol}{CODE};    # export subs only

        my $imported = $caller . '::' . $name;
        *{ $imported } = \*{ $symbol };
    }
}

Chas. Owens ,

Warning, the code following is as bad an idea as exporting everything:
package Expo;

use base "Exporter";

seek DATA, 0, 0; #move DATA back to package

#read this file looking for sub names
our @EXPORT = map { /^sub\s+([^({\s]+)/ ? $1 : () } <DATA>;

my $sub = sub {}; #make sure anon funcs aren't grabbed

sub foo($) {
    print shift, "\n";
}

sub bar ($) {
    print shift, "\n";
}

sub baz{
    print shift,"\n";
}

sub quux {
    print shift,"\n";
}

1;

__DATA__

Here is the some code that uses the module:

#!/usr/bin/perl

use strict;
use warnings;

use Expo;

print map { "[$_]\n" } @Expo::EXPORT;

foo("foo");
bar("bar");
baz("baz");
quux("quux");

And here is its output:

[foo]
[bar]
[baz]
[quux]
foo
bar
baz
quux

Jon Ericson , 2009-04-08 22:33:36

You can always call subroutines in there fully-specified form:
MyModule::firstsub();

For modules I write internally, I find this convention works fairly well. It's a bit more typing, but tends to be better documentation.

Take a look at perldoc perlmod for more information about what you are trying to accomplish.

More generally, you could look at Exporter 's code and see how it uses glob aliasing. Or you can examine your module's namespace and export each subroutine. (I don't care to search for how to do that at the moment, but Perl makes this fairly easy.) Or you could just stick your subroutines in the main package:

 package main;
 sub firstsub() { ... }

(I don't think that's a good idea, but you know better than I do what you are trying to accomplish.)

There's nothing wrong with doing this provided you know what you are doing and aren't just trying to avoid thinking about your interface to the outside world.

ysth , 2009-04-09 01:29:04

Perhaps you would be interested in one of the Export* modules on CPAN that lets you mark subs as exportable simply by adding an attribute to the sub definition? (Don't remember which one it was, though.)

echo , 2014-10-11 18:23:01

https://metacpan.org/pod/Exporter::Auto

Exporter::Auto. this is all you need.

Tero Niemi , 2013-04-02 00:32:25

Although it is not usually wise to dump all sub s from module into the caller namespace, it is sometimes useful (and more DRY!) to automatically generate @EXPORT_OK and %EXPORT_TAGS variables.

The easiest method is to extend the Exporter. A simple example is something like this:

package Exporter::AutoOkay;
#
#   Automatically add all subroutines from caller package into the
#   @EXPORT_OK array. In the package use like Exporter, f.ex.:
#
#       use parent 'Exporter::AutoOkay';
#
use warnings;
use strict;
no strict 'refs';

require Exporter;

sub import {
    my $package = $_[0].'::';

    # Get the list of exportable items
    my @export_ok = (@{$package.'EXPORT_OK'});

    # Automatically add all subroutines from package into the list
    foreach (keys %{$package}) {
        next unless defined &{$package.$_};
        push @export_ok, $_;
    }

    # Set variable ready for Exporter
    @{$package.'EXPORT_OK'} = @export_ok;

    # Let Exporter do the rest
    goto &Exporter::import;
}

1;

Note the use of goto that removes us from the caller stack.

A more complete example can be found here: http://pastebin.com/Z1QWzcpZ It automatically generates tag groups from subroutine prefixes.

Sérgio , 2013-11-14 21:38:06

case 1

Library is :

package mycommon;

use strict;
use warnings;

sub onefunctionthatyoumadeonlibary() {
}
1;

you can use it, calling common:: :

#!/usr/bin/perl
use strict;
use warnings;
use mycommon;

common::onefunctionthatyoumadeonlibary()
case 2

Library is , yousimple export them :

package mycommon;

use strict;
use warnings;

use base 'Exporter';

our @EXPORT = qw(onefunctionthatyoumadeonlibary);
sub onefunctionthatyoumadeonlibary() {
}
1;

use it in same "namespace":

#!/usr/bin/perl
use strict;
use warnings;
use mycommon qw(onefunctionthatyoumadeonlibary);

onefunctionthatyoumadeonlibary()

Also we can do a mix of this two cases , we can export more common functions to use it without calling the packages name and other functions that we only call it with package name and that ones don't need to be exported.

> ,

You will have to do some typeglob munging. I describe something similar here:

Is there a way to "use" a single file that in turn uses multiple others in Perl?

The import routine there should do exactly what you want -- just don't import any symbols into your own namespace.

[Dec 01, 2019] function - How can I export all subs in a Perl package - Stack Overflow

Jan 01, 2009 | stackoverflow.com

How can I export all subs in a Perl package? Ask Question Asked 10 years, 7 months ago Active 3 years, 5 months ago Viewed 18k times


Ville M ,

I would like to expose all subs into my namespace without having to list them one at a time:
@EXPORT = qw( firstsub secondsub third sub etc );

Using fully qualified names would require bunch of change to existing code so I'd rather not do that.

Is there @EXPORT_ALL?

I think documentation says it's a bad idea, but I'd like to do it anyway, or at least know how.

To answer Jon's why: right now for quick refactoring I want to move of bunch of subs into their own package with least hassle and code changes to the existing scripts (where those subs are currenty used and often repeated).

Also, mostly, I was just curious. (since it seemed like that Exporter might as well have that as standard feature, but somewhat surprisingly based on answers so far it doesn't)

brian d foy , 2009-04-08 23:58:35

Don't do any exporting at all, and don't declare a package name in your library. Just load the file with require and everything will be in the current package. Easy peasy.

Michael Carman , 2009-04-09 00:15:10

Don't. But if you really want to... write a custom import that walks the symbol table and export all the named subroutines.
# Export all subs in package. Not for use in production code!
sub import {
    no strict 'refs';

    my $caller = caller;

    while (my ($name, $symbol) = each %{__PACKAGE__ . '::'}) {
        next if      $name eq 'BEGIN';   # don't export BEGIN blocks
        next if      $name eq 'import';  # don't export this sub
        next unless *{$symbol}{CODE};    # export subs only

        my $imported = $caller . '::' . $name;
        *{ $imported } = \*{ $symbol };
    }
}

Chas. Owens ,

Warning, the code following is as bad an idea as exporting everything:
package Expo;

use base "Exporter";

seek DATA, 0, 0; #move DATA back to package

#read this file looking for sub names
our @EXPORT = map { /^sub\s+([^({\s]+)/ ? $1 : () } <DATA>;

my $sub = sub {}; #make sure anon funcs aren't grabbed

sub foo($) {
    print shift, "\n";
}

sub bar ($) {
    print shift, "\n";
}

sub baz{
    print shift,"\n";
}

sub quux {
    print shift,"\n";
}

1;

__DATA__

Here is the some code that uses the module:

#!/usr/bin/perl

use strict;
use warnings;

use Expo;

print map { "[$_]\n" } @Expo::EXPORT;

foo("foo");
bar("bar");
baz("baz");
quux("quux");

And here is its output:

[foo]
[bar]
[baz]
[quux]
foo
bar
baz
quux

Jon Ericson , 2009-04-08 22:33:36

You can always call subroutines in there fully-specified form:
MyModule::firstsub();

For modules I write internally, I find this convention works fairly well. It's a bit more typing, but tends to be better documentation.

Take a look at perldoc perlmod for more information about what you are trying to accomplish.

More generally, you could look at Exporter 's code and see how it uses glob aliasing. Or you can examine your module's namespace and export each subroutine. (I don't care to search for how to do that at the moment, but Perl makes this fairly easy.) Or you could just stick your subroutines in the main package:

 package main;
 sub firstsub() { ... }

(I don't think that's a good idea, but you know better than I do what you are trying to accomplish.)

There's nothing wrong with doing this provided you know what you are doing and aren't just trying to avoid thinking about your interface to the outside world.

ysth , 2009-04-09 01:29:04

Perhaps you would be interested in one of the Export* modules on CPAN that lets you mark subs as exportable simply by adding an attribute to the sub definition? (Don't remember which one it was, though.)

echo , 2014-10-11 18:23:01

https://metacpan.org/pod/Exporter::Auto

Exporter::Auto. this is all you need.

Tero Niemi , 2013-04-02 00:32:25

Although it is not usually wise to dump all sub s from module into the caller namespace, it is sometimes useful (and more DRY!) to automatically generate @EXPORT_OK and %EXPORT_TAGS variables.

The easiest method is to extend the Exporter. A simple example is something like this:

package Exporter::AutoOkay;
#
#   Automatically add all subroutines from caller package into the
#   @EXPORT_OK array. In the package use like Exporter, f.ex.:
#
#       use parent 'Exporter::AutoOkay';
#
use warnings;
use strict;
no strict 'refs';

require Exporter;

sub import {
    my $package = $_[0].'::';

    # Get the list of exportable items
    my @export_ok = (@{$package.'EXPORT_OK'});

    # Automatically add all subroutines from package into the list
    foreach (keys %{$package}) {
        next unless defined &{$package.$_};
        push @export_ok, $_;
    }

    # Set variable ready for Exporter
    @{$package.'EXPORT_OK'} = @export_ok;

    # Let Exporter do the rest
    goto &Exporter::import;
}

1;

Note the use of goto that removes us from the caller stack.

A more complete example can be found here: http://pastebin.com/Z1QWzcpZ It automatically generates tag groups from subroutine prefixes.

Sérgio , 2013-11-14 21:38:06

case 1

Library is :

package mycommon;

use strict;
use warnings;

sub onefunctionthatyoumadeonlibary() {
}
1;

you can use it, calling common:: :

#!/usr/bin/perl
use strict;
use warnings;
use mycommon;

common::onefunctionthatyoumadeonlibary()
case 2

Library is , yousimple export them :

package mycommon;

use strict;
use warnings;

use base 'Exporter';

our @EXPORT = qw(onefunctionthatyoumadeonlibary);
sub onefunctionthatyoumadeonlibary() {
}
1;

use it in same "namespace":

#!/usr/bin/perl
use strict;
use warnings;
use mycommon qw(onefunctionthatyoumadeonlibary);

onefunctionthatyoumadeonlibary()

Also we can do a mix of this two cases , we can export more common functions to use it without calling the packages name and other functions that we only call it with package name and that ones don't need to be exported.

> ,

You will have to do some typeglob munging. I describe something similar here:

Is there a way to "use" a single file that in turn uses multiple others in Perl?

The import routine there should do exactly what you want -- just don't import any symbols into your own namespace.

[Nov 23, 2019] Introduction to Perl Modules

Nov 23, 2019 | ods.com.ua

CONTENTS


This chapter introduces you to the concepts behind references to Perl modules, packages, and classes. It also shows you how to create a few sample modules.

What Is a Perl Module?

A Perl module is a set of Perl code that acts like a library of function calls. The term module in Perl is synonymous with the word package . Packages are a feature of Perl 4, whereas modules are prevalent in Perl 5.

You can keep all your reusable Perl code specific to a set of tasks in a Perl module. Therefore, all the functionality pertaining to one type of task is contained in one file. It's easier to build an application on these modular blocks. Hence, the word module applies a bit more than package .

Here's a quick introduction to modules. Certain topics in this section will be covered in detail throughout the rest of the book. Read the following paragraphs carefully to get an overview of what lies ahead as you write and use your own modules.

What is confusing is that the terms module and package are used interchangeably in all Perl documentation, and these two terms mean the very same thing . So when reading Perl documents, just think "package" when you see "module" and vice versa.

So, what's the premise for using modules? Well, modules are there to package (pardon the pun) variables, symbols, and interconnected data items together. For example, using global variables with very common names such as $k , $j , or $i in a program is generally not a good idea. Also, a loop counter, $i , should be allowed to work independently in two different portions of the code. Declaring $i as a global variable and then incrementing it from within a subroutine will create unmanageable problems with your application code because the subroutine may have been called from within a loop that also uses a variable called $i . The use of modules in Perl allows variables with the same name to be created at different, distinct places in the same program.

The symbols defined for your variables are stored in an associative array, referred to as a symbol table . These symbol tables are unique to a package. Therefore, variables of the same name in two different packages can have different values.

Each module has its own symbol table of all symbols that are declared within it. The symbol table basically isolates synonymous names in one module from another. The symbol table defines a namespace , that is, a space for independent variable names to exist in. Thus, the use of modules, each with its own symbol table, prevents a variable declared in one section from overwriting the values of other variables with the same name declared elsewhere in the same program.

As a matter of fact, all variables in Perl belong to a package. The variables in a Perl program belong to the main package. All other packages within a Perl program either are nested within this main package or exist at the same level. There are some truly global variables, such as the signal handler array %SIG , that are available to all other modules in an application program and cannot be isolated via namespaces. Only those variable identifiers starting with letters or an underscore are kept in a module's symbol table. All other symbols, such as the names STDIN , STDOUT , STDERR , ARGV , ARGVOUT , ENV , Inc , and SIG are forced to be in package _main.

Switching between packages affects only namespaces. All you are doing when you use one package or another is declaring which symbol table to use as the default symbol table for lookup of variable names. Only dynamic variables are affected by the use of symbol tables. Variables declared by the use of the my keyword are still resolved with the code block they happen to reside in and are not referenced through symbol tables. In fact, the scope of a package declaration remains active only within the code block it is declared in. Therefore, if you switch symbol tables by using a package within a subroutine, the original symbol table in effect when the call was made will be restored when the subroutine returns.

Switching symbol tables affects only the default lookup of dynamic variable names. You can still explicitly refer to variables, file handles, and so on in a specific package by prepending a packageName :: to the variable name. You saw what a package context was when using references in Chapter 3 . A package context simply implies the use of the symbol table by the Perl interpreter for resolving variable names in a program. By switching symbol tables, you are switching the package context.

Modules can be nested within other modules. The nested module can use the variables and functions of the module it is nested within. For nested modules, you would have to use moduleName :: nestedModuleName and so on. Using the double colon ( :: ) is synonymous with using a back quote ( ` ). However, the double colon is the preferred, future way of addressing variables within modules.

Explicit addressing of module variables is always done with a complete reference. For example, suppose you have a module, Investment , which is the default package in use, and you want to address another module, Bonds , which is nested within the Investment module. In this case, you cannot use Bond:: . Instead, you would have to use Investment::Bond:: to address variables and functions within the Bond module. Using Bond:: would imply the use of a package Bond that is nested within the main module and not within the Investment module.

The symbol table for a module is actually stored in an associative array of the module's names appended with two colons. The symbol table for a module called Bond will be referred to as the associative array %Bond:: . The name for the symbol table for the main module is %main:: , and can even be shortened to %:: . Similarly, all nested packages have their symbols stored in associative arrays with double colons separating each nesting level. For example, in the Bond module that is nested within the Investment module, the associative array for the symbols in the Bond module will be named %Investment::Bond:: .

A typeglob is really a global type for a symbol name. You can perform aliasing operations by assigning to a typeglob . One or more entries in an associative array for symbols will be used when an assignment via a typeglob is used. The actual value in each entry of the associative array is what you are referring to when you use the * variableName notation. Thus, there are two ways of referring to variable names in a package:

*Investment::money = *Investment::bills;

$Investment::{'money'} = $Investment::{'bills'};

In the first method, you are referring to the variables via a typeglob reference. The use of the symbol table, %Investment:: , is implied here, and Perl will optimize the lookup for symbols money and bills . This is the faster and preferred way of addressing a symbol. The second method uses a lookup for the value of a variable addressed by 'money' and 'bills' in the associative array used for symbols, %Investment:: explicitly. This lookup would be done dynamically and will not be optimized by Perl. Therefore, the lookup will be forced to check the associative array every time the statement is executed. As a result, the second method is not efficient and should be used only for demonstration of how the symbol table is implemented internally.

Another example in this statement

*kamran = *husain;

causes variables, subroutines, and file handles that are named via the symbol kamran to also be addressed via the symbol husain . That is, all symbol entries in the current symbol table with the key kamran will now contain references to those symbols addressed by the key husain . To prevent such a global assignment, you can use explicit references. For example, the following statement will let you address the contents of $husain via the variable $kamran :

*kamran = \$husain;

However, any arrays such @kamran and @husain will not be the same. Only what the references specified explicitly will be changed. To summarize, when you assign one typeglob to another, you affect all the entries in a symbol table regardless of the type of variable being referred to. When you assign a reference from one variable type to another, you are only affecting one entry in the symbol table.

A Perl module file has the following format:

package ModuleName;
...
#### Insert module code ####
...
1;

The filename has to be called ModuleName.pm . The name of a module must end in the string .pm by convention. The package statement is the first line of the file. The last line of the file must contain the line with the 1; statement. This in effect returns a true value to the application program using the module. Not using the 1; statement will not let the module be loaded correctly.

The package statement tells the Perl interpreter to start with a new namespace domain. Basically, all your variables in a Perl script belong to a package called main . Every variable in the main package can be referred to as $main'variable .

Here's the syntax for such references:

$packageName'variableName

The single quote ( ' ) is synonymous with the double colon ( :: ) operator. I cover more uses of the :: operator in the next chapter. For the time being, you must remember that the following two statements are equivalent:

$packageName'variableName;
$packageName::variableName;

The double-colon syntax is considered standard in the Perl world. Therefore, to preserve readability, I use the double-colon syntax in the rest of this book unless it's absolutely necessary to make exceptions to prove a point.

The default use of a variable name defers to the current package active at the time of compilation. Thus, if you are in the package Finance.pm and specify a variable $pv , the variable is actually equal to $Finance::$pv .

Using Perl Modules: use vs. require

You include Perl modules in your program by using the use or the require statement. Here's the way to use either of these statements:

use ModuleName;
require ModuleName;

Note that the .pm extension is not used in the code shown above. Also note that neither statement allows a file to be included more than once in a program. The returned value of true ( 1; ) as the last statement is required to let Perl know that a require d or use d module loaded correctly and lets the Perl interpreter ignore any reloads. In general, it's better to use the use Module; statement than the require Module; statement in a Perl program to remain compatible with future versions of Perl.

For modules, you might want to consider continuing to use the require statement. Here's why: The use statement does a little bit more work than the require statement in that it alters the namespace of the module that includes another module. You want this extra update of the namespace to be done in a program. However, when writing code for a module, you may not want the namespace to be altered unless it's explicitly required. In this event, you will use the require statement.

The require statement includes the full pathname of a file in the @Inc array so that the functions and variables in the module's file are in a known location during execution time. Therefore, the functions that are imported from a module are imported via an explicit module reference at runtime with the require statement. The use statement does the same thing as the require statement because it updates the @Inc array with full pathnames of loaded modules. The code for the use function also goes a step further and calls an import function in the module being use d to explicitly load the list of exported functions at compile time, thus saving the time required for an explicit resolution of a function name during execution.

Basically, the use statement is equivalent to

require ModuleName; import ModuleName [list of imported functions];

The use of the use statement does change your program's namespace because the imported function names are inserted in the symbol table. The require statement does not alter your program's namespace. Therefore, the following statement

use ModuleName ();

is equivalent to this statement:

require ModuleName;

Functions are imported from a module via a call to a function called import . You can write your own import function in a module, or you can use the Exporter module and use its import function. In almost all cases, you will use the Exporter module to provide an import function instead of reinventing the wheel. (You'll learn more on this in the next section.) Should you decide not to use the Exporter module, you will have to write your own import function in each module that you write. It's much easier to simply use the Exporter module and let Perl do the work for you.

The Sample Letter.pm Module

The best way to illustrate the semantics of how a module is used in Perl is to write a simple module and show how to use it. Let's take the example of a local loan shark, Rudious Maximus, who is simply tired of typing the same "request for payment" letters. Being an avid fan of computers and Perl, Rudious takes the lazy programmer's approach and writes a Perl module to help him generate his memos and letters.

Now, instead of typing within fields in a memo template file, all he has to do is type a few lines to produce his nice, threatening note. Listing 4.1 shows you what he has to type.


Listing 4.1. Using the Letter module.
1 #!/usr/bin/perl -w
2 #
3 # Uncomment the line below to include the current dir in @Inc.
4 # push (@Inc, 'pwd');
5 #
6 use Letter;
7
8 Letter::To("Mr. Gambling Man","The money for Lucky Dog, Race 2");
9 Letter::ClaimMoneyNice();
10 Letter::ThankDem();
11 Letter::Finish();

The use Letter; statement is present to force the Perl interpreter to include the code for the module in the application program. The module should be located in the /usr/lib/perl5/ directory, or you can place it in any directory listed in the @Inc array. The @Inc array is the list of directories that the Perl interpreter will look for when attempting to load the code for the named module. The commented line (number 4) shows how to add the current working directory to include the path. The next four lines in the file generate the subject matter for the letter.

Here's the output from using the Letter module:

To: Mr. Gambling Man
Fm: Rudious Maximus, Loan Shark
Dt: Wed Feb 7 10:35:51 CST 1996

Re: The money for Lucky Dog, Race 2

====================================================

It has come to my attention that your account is
way over due.
You gonna pay us soon?
Or would you like me to come ovah?

Thanks for your support.

Sincerely,
Rudious

The Letter module file is shown in Listing 4.2. The name of the package is declared in the first line. Because this module's functions will be exported, I use the Exporter module. Therefore, the statement use Exporter; is required to inherit functionality from the Exporter module. Another required step is putting the word Exported in the @ISA array to allow searching for Exported.pm .

Note
The @ISA array is a special array within each package. Each item in the array lists where else to look for a method if it cannot be found in the current package. The order in which packages are listed in the @ISA array is the order in which Perl searches for unresolved symbols. A class that is listed in the @ISA array is referred to as the base class of that particular class. Perl will cache missing methods found in base classes for future references. Modifying the @ISA array will flush the cache and cause Perl to look up all methods again.

Let's now look at the code for Letter.pm in Listing 4.2.


Listing 4.2. The Letter.pm module.
1 package Letter;
2
3 require Exporter;
4 @ISA = (Exporter);
5
6 =head1 NAME
7
8 Letter - Sample module to generate letterhead for you
9
10 =head1 SYNOPSIS
11
12 use Letter;
13
14 Letter::Date();
15 Letter::To($name,$company,$address);
16
17 Then one of the following:
18 Letter::ClaimMoneyNice() {
19 Letter::ClaimMoney();
20 Letter::ThreatBreakLeg();
21
22 Letter::ThankDem();
23 Letter::Finish();
24
25 =head1 DESCRIPTION
26
27 This module provides a short example of generating a letter for a
28 friendly neighborbood loan shark.
29
30 The code begins after the "cut" statement.
31 =cut
32
33 @EXPORT = qw( Date,
34 To,
35 ClaimMoney,
36 ClaimMoneyNice,
37 ThankDem,
38 Finish );
39
40 #
41 # Print today's date
42 #
43 sub Letter::Date {
44 $date = 'date';
45 print "\n Today is $date";
46 }
47
48 sub Letter::To {
49 local($name) = shift;
50 local($subject) = shift;
51 print "\n To: $name";
52 print "\n Fm: Rudious Maximus, Loan Shark";
53 print "\n Dt: ", `date`;
54 print "\n Re: $subject";
55 print "\n\n";
56 print "\n====================================================\n";
57 }
58 sub Letter::ClaimMoney() {
59 print "\n You owe me money. Get your act together";
60 print "\n Do you want me to send Bruno over to ";
61 print "\n collect it , or are you gonna pay up?";
62 }
63
64 sub Letter::ClaimMoneyNice() {
65 print "\n It is come to my attention that your account is ";
66 print "\n way over due.";
67 print "\n You gonna pay us soon..";
68 print "\n or would you like me to come ovah?";
69 }
70
71 sub Letter::ThreatBreakLeg() {
72 print "\n apparently letters like these dont help";
73 print "\n I will have to make an example of you";
74 print "\n \n See you in the hospital, pal!";
75 }
76
77 sub Letter::ThankDem() {
78 print "\n\n Thanks for your support";
79 }
80
81 sub Letter::Finish(){
82 printf "\n\n\n\n Sincerely";
83 printf "\n Rudious \n ";
84 }
85
86 1;

Lines containing the equal sign are used for documentation. You must document each module for your own reference; Perl modules do not need to be documented, but it's a good idea to write a few lines about what your code does. A few years from now, you may forget what a module is about. Good documentation is always a must if you want to remember what you did in the past!

I cover documentation styles used for Perl in Chapter 8 , "Documenting Perl Scripts." For this sample module, the =head1 statement begins the documentation. Everything up to the =cut statement is ignored by the Perl interpreter.

Next, the module lists all the functions exported by this module in the @EXPORT array. The @EXPORT array defines all the function names that can be called by outside code. If you do not list a function in this @EXPORT array, it won't be seen by external code modules.

Following the @EXPORT array is the body of the code, one subroutine at a time. After all the subroutines are defined, the final statement 1; ends the module file. 1; must be the last executable line in the file.

Let's look at some of the functions defined in this module. The first function to look at is the simple Date function, lines 43 to 46, which prints the current UNIX date and time. There are no parameters to this function, and it doesn't return anything meaningful back to the caller.

Note the use of my before the $date variable in line 44. The my keyword is used to limit the scope of the variable to within the Date function's curly braces. Code between curly braces is referred to as a block . Variables declared within a block are limited in scope to within the curly braces. In 49 and 50, the local variables $name and $subject are visible to all functions.

You can also declare variables with the local qualifier. The use of local allows a variable to be in scope for the current block as well as for other blocks of code called from within this block. Thus, a local $x declared within one block is visible to all subsequent blocks called from within this block and can be referenced. In the following sample code, the ToTitled function's $name variable can be accessed but not the data in $iphone :

1 sub Letter::ToTitled {
2 local($name) = shift;
3 my($phone) = shift;
Subroutines and Passing Parameters

The sample code for Letter.pm showed how to extract one parameter at a time. The subroutine To() takes two parameters to set up the header for the memo.

Using functions within a module is not any different than using and defining Perl modules within the same code file. Parameters are passed by reference unless otherwise specified. Multiple arrays passed into a subroutine, if not explicitly dereferenced using the backslash, are concatenated.

The @_ input array in a function is always an array of scalar values. Passing values by reference is the preferred way in Perl to pass a large amount of data into a subroutine. ( See Chapter 3 , "References.")

Another Sample Module: Finance

The Finance module, shown in Listing 4.3, is used to provide simple calculations for loan values. Using the Finance module is straightforward. All the functions are written with the same parameters, as shown in the formula for the functions.

Let's look at how the future value of an investment can be calculated. For example, if you invest some dollars, $pv , in a bond that offers a fixed percentage rate, $r , applied at known intervals for $n time periods, what is the value of the bond at the time of its expiration? In this case, you'll be using the following formula:

$fv = $pv * (1+$r) ** $n ;

The function to get the future value is declared as FutureValue . Refer to Listing 4.3 to see how to use it.


Listing 4.3. Using the Finance module.
1 #!/usr/bin/perl -w
2
3 push(@Inc,'pwd');
4 use Finance;
5
6 $loan = 5000.00;
7 $apr = 3.5; # APR
8 $year = 10; # in years.
9
10 # ----------------------------------------------------------------
11 # Calculate the value at the end of the loan if interest
12 # is applied every year.
13 # ----------------------------------------------------------------
14 $time = $year;
15 $fv1 = Finance::FutureValue($loan,$apr,$time);
16 print "\n If interest is applied at end of year";
17 print "\n The future value for a loan of \$" . $loan . "\n";
18 print " at an APR of ", $apr , " for ", $time, " years";
19 printf " is %8.2f \n" , $fv1;
20
21 # ----------------------------------------------------------------
22 # Calculate the value at the end of the loan if interest
23 # is applied every month.
24 # ----------------------------------------------------------------
25 $rate = $apr / 12; # APR
26 $time = $year * 12; # in months
27 $fv2 = Finance::FutureValue($loan,$rate,$time);
28
29 print "\n If interest is applied at end of each month";
30 print "\n The future value for a loan of \$" . $loan . "\n";
31 print " at an APR of ", $apr , " for ", $time, " months";
32 printf " is %8.2f \n" , $fv2;
33
34 printf "\n The difference in value is %8.2f", $fv2 - $fv1;
35 printf "\n Therefore by applying interest at shorter time periods";
36 printf "\n we are actually getting more money in interest.\n";

Here is sample input and output of Listing 4.3.

$ testme

If interest is applied at end of year
The future value for a loan of $5000
at an APR of 3.5 for 10 years is 7052.99

If interest is applied at end of each month
The future value for a loan of $5000
at an APR of 3.5 for 120 months is 7091.72

The difference in value is 38.73
Therefore by applying interest at shorter time periods
we are actually getting more money in interest.

The revelation in the output is the result of the comparison of values between $fv1 and $fv2 . The $fv1 value is calculated with the application of interest once every year over the life of the bond. $fv2 is the value if the interest is applied every month at the equivalent monthly interest rate.

The Finance.pm package is shown in Listing 4.4 in its early development stages.


Listing 4.4. The Finance.pm package.
1 package Finance;
2
3 require Exporter;
4 @ISA = (Exporter);
5
6 =head1 Finance.pm
7
8 Financial Calculator - Financial calculations made easy with Perl
9
10 =head 2
11 use Finance;
12
13 $pv = 10000.0;
14
15 $rate = 12.5 / 12; # APR per month.
16
17 $time = 360 ; # months for loan to mature
18
19 $fv = FutureValue();
20
21 print $fv;
22
23 =cut
24
25 @EXPORT = qw( FutureValue,
26 PresentValue,
27 FVofAnnuity,
28 AnnuityOfFV,
29 getLastAverage,
30 getMovingAverage,
31 SetInterest);
32
33 #
34 # Globals, if any
35 #
36
37 local $defaultInterest = 5.0;
38
39 sub Finance::SetInterest($) {
40 my $rate = shift(@_);
41 $defaultInterest = $rate;
42 printf "\n \$defaultInterest = $rate";
43 }
44
45 # --------------------------------------------------------------------
46 # Notes:
47 # 1. The interest rate $r is given in a value of [0-100].
48 # 2. The $n given in the terms is the rate at which the interest
49 # is applied.
50 #
51 # --------------------------------------------------------------------
52
53 # --------------------------------------------------------------------
54 # Present value of an investment given
55 # fv - a future value
56 # r - rate per period
57 # n - number of period
58 # --------------------------------------------------------------------
59 sub Finance::FutureValue($$$) {
60 my ($pv,$r,$n) = @_;
61 my $fv = $pv * ((1 + ($r/100)) ** $n);
62 return $fv;
63 }
64
65 # --------------------------------------------------------------------
66 # Present value of an investment given
67 # fv - a future value
68 # r - rate per period
69 # n - number of period
70 # --------------------------------------------------------------------
71 sub Finance::PresentValue($$$) {
72 my $pv;
73 my ($fv,$r,$n) = @_;
74 $pv = $fv / ((1 + ($r/100)) ** $n);
75 return $pv;
76
77 }
78
79 # --------------------------------------------------------------------
80 # Get the future value of an annuity given
81 # mp - Monthly Payment of Annuity
82 # r - rate per period
83 # n - number of period
84 # --------------------------------------------------------------------
85
86 sub FVofAnnuity($$$) {
87 my $fv;
88 my $oneR;
89 my ($mp,$r,$n) = @_;
90
91 $oneR = ( 1 + $r) ** $n;
92 $fv = $mp * ( ($oneR - 1)/ $r);
93 return $fv;
94 }
95
96 # --------------------------------------------------------------------
97 # Get the annuity from the following bits of information
98 # r - rate per period
99 # n - number of period
100 # fv - Future Value
101 # --------------------------------------------------------------------
102
103 sub AnnuityOfFV($$$) {
104 my $mp; # mp - Monthly Payment of Annuity
105 my $oneR;
106 my ($fv,$r,$n) = @_;
107
108 $oneR = ( 1 + $r) ** $n;
109 $mp = $fv * ( $r/ ($oneR - 1));
110 return $mp;
111 }
112
113 # --------------------------------------------------------------------
114 # Get the average of the last "n" values in an array.
115 # --------------------------------------------------------------------
116 # The last $count number of elements from the array in @values
117 # The total number of elements in @values is in $number
118 #
119 sub getLastAverage($$@) {
120 my ($count, $number, @values) = @_;
121 my $i;
122
123 my $a = 0;
124 return 0 if ($count == 0);
125 for ($i = 0; $i< $count; $i++) {
126 $a += $values[$number - $i - 1];
127 }
128 return $a / $count;
129 }
130
131 # --------------------------------------------------------------------
132 # Get a moving average of the values.
133 # --------------------------------------------------------------------
134 # The window size is the first parameter, the number of items in the
135 # passed array is next. (This can easily be calculated within the
136 # function using the scalar() function, but the subroutine shown here
137 # is also being used to illustrate how to pass pointers.) The reference to the
138 # array of values is passed next, followed by a reference to the place
139 # the return values are to be stored.
140 #
141 sub getMovingAve($$\@\@) {
142 my ($count, $number, $values, $movingAve) = @_;
143 my $i;
144 my $a = 0;
145 my $v = 0;
146
147 return 0 if ($count == 0);
148 return -1 if ($count > $number);
149 return -2 if ($count < 2);
150
151 $$movingAve[0] = 0;
152 $$movingAve[$number - 1] = 0;
153 for ($i=0; $i<$count;$i++) {
154 $v = $$values[$i];
155 $a += $v / $count;
156 $$movingAve[$i] = 0;
157 }
158 for ($i=$count; $i<$number;$i++) {
159 $v = $$values[$i];
160 $a += $v / $count;
161 $v = $$values[$i - $count - 1];
162 $a -= $v / $count;
163 $$movingAve[$i] = $a;
164 }
165 return 0;
166 }
167
168 1;

Look at the declaration of the function FutureValue with ($$$) . The three dollar signs together signify three scalar numbers being passed into the function. This extra scoping is present for validating the type of the parameters passed into the function. If you were to pass a string instead of a number into the function, you would get a message very similar to this one:

Too many arguments for Finance::FutureValue at ./f4.pl line 15, near "$time)"
Execution of ./f4.pl aborted due to compilation errors.

The use of prototypes when defining functions prevents you from sending in values other than what the function expects. Use @ or % to pass in an array of values. If you are passing by reference, use \@ or \% to show a scalar reference to an array or hash, respectively. If you do not use the backslash, all other types in the argument list prototype are ignored. Other types of disqualifiers include an ampersand for a reference to a function, an asterisk for any type, and a semicolon to indicate that all other parameters are optional.

Now, let's look at the lastMovingAverage function declaration, which specifies two integers in the front followed by an array. The way the arguments are used in the function is to assign a value to each of the two scalars, $count and $number , whereas everything else is sent to the array. Look at the function getMovingAverage() to see how two arrays are passed in order to get the moving average on a list of values.

The way to call the getMovingAverage function is shown in Listing 4.5.


Listing 4.5. Using the moving average function.
1 #!/usr/bin/perl -w
2
3 push(@Inc,'pwd');
4 use Finance;
5
6 @values = ( 12,22,23,24,21,23,24,23,23,21,29,27,26,28 );
7 @mv = (0);
8 $size = scalar(@values);
9 print "\n Values to work with = { @values } \n";
10 print " Number of values = $size \n";
11
12 # ----------------------------------------------------------------
13 # Calculate the average of the above function
14 # ----------------------------------------------------------------
15 $ave = Finance::getLastAverage(5,$size,@values);
16 print "\n Average of last 5 days = $ave \n";
17
18 Finance::getMovingAve(5,$size,@values,@mv);
19 print "\n Moving Average with 5 days window = \n { @mv } \n";

Here's the output from Listing 4.5:

Values to work with = { 12 22 23 24 21 23 24 23 23 21 29 27 26 28 }
Number of values = 14

Average of last 5 days = 26.2

Moving Average with 5 days window =
{ 0 0 0 0 0 19.4 21.8 22 22 21.4 23 23.8 24.2 25.2 }

The getMovingAverage() function takes two scalars and then two references to arrays as scalars. Within the function, the two scalars to the arrays are dereferenced for use as numeric arrays. The returned set of values is inserted in the area passed in as the second reference. Had the input parameters not been specified with \@ for each referenced array, the $movingAve array reference would have been empty and would have caused errors at runtime. In other words, the following declaration is not correct:

sub getMovingAve($$@@)

The resulting spew of error messages from a bad function prototype is as follows:

Use of uninitialized value at Finance.pm line 128.
Use of uninitialized value at Finance.pm line 128.
Use of uninitialized value at Finance.pm line 128.
Use of uninitialized value at Finance.pm line 128.
Use of uninitialized value at Finance.pm line 128.
Use of uninitialized value at Finance.pm line 133.
Use of uninitialized value at Finance.pm line 135.
Use of uninitialized value at Finance.pm line 133.
Use of uninitialized value at Finance.pm line 135.
Use of uninitialized value at Finance.pm line 133.
Use of uninitialized value at Finance.pm line 135.
Use of uninitialized value at Finance.pm line 133.
Use of uninitialized value at Finance.pm line 135.
Use of uninitialized value at Finance.pm line 133.
Use of uninitialized value at Finance.pm line 135.
Use of uninitialized value at Finance.pm line 133.
Use of uninitialized value at Finance.pm line 135.
Use of uninitialized value at Finance.pm line 133.
Use of uninitialized value at Finance.pm line 135.
Use of uninitialized value at Finance.pm line 133.
Use of uninitialized value at Finance.pm line 135.
Use of uninitialized value at Finance.pm line 133.
Use of uninitialized value at Finance.pm line 135.

Values to work with = { 12 22 23 24 21 23 24 23 23 21 29 27 26 28 }
Number of values = 14

Average of last 5 days = 26.2

Moving Average with 5 days window =
{ 0 }

This is obviously not the correct output. Therefore, it's critical that you pass by reference when sending more than one array.

Global variables for use within the package can also be declared. Look at the following segment of code from the Finance.pm module to see what the default value of the Interest variable would be if nothing was specified in the input. (The current module requires the interest to be passed in, but you can change this.)

Here's a little snippet of code that can be added to the end of the program shown in Listing 4.5 to add the ability to set interest rates.

20 local $defaultInterest = 5.0;
21 sub Finance::SetInterest($) {
22 my $rate = shift(@_);
23 $rate *= -1 if ($rate < 0);
24 $defaultInterest = $rate;
25 printf "\n \$defaultInterest = $rate";
26 }

The local variable $defaultInterest is declared in line 20. The subroutine SetInterest to modify the rate is declared in lines 21 through 26. The $rate variable uses the values passed into the subroutine and simply assigns a positive value for it. You can always add more error checking if necessary.

To access the defaultInterest variable's value, you could define either a subroutine that returns the value or refer to the value directly with a call to the following in your application program:

$Finance::defaultInterest;
Returned Values from Subroutines in a Package

The variable holding the return value from the module function is declared as my variable . The scope of this variable is within the curly braces of the function only. When the called subroutine returns, the reference to my variable is returned. If the calling program uses this returned reference somewhere, the link counter on the variable is not zero; therefore, the storage area containing the returned values is not freed to the memory pool. Thus, the function that declares

my $pv

and then later returns the value of $pv returns a reference to the value stored at that location. If the calling routine performs a call like this one:

Finance::FVofAnnuity($monthly,$rate,$time);

there is no variable specified here into which Perl stores the returned reference; therefore, any returned value (or a list of values) is destroyed. Instead, the call with the returned value assigned to a local variable, such as this one:

$fv = Finance::FVofAnnuity($monthly,$rate,$time);

maintains the variable with the value. Consider the example shown in Listing 4.6, which manipulates values returned by functions.


Listing 4.6. Sample usage of the my function.
1 #!/usr/bin/perl -w
2
3 push(@Inc,'pwd');
4 use Finance;
5
6 $monthly = 400;
7 $rate = 0.2; # i.e. 6 % APR
8 $time = 36; # in months
9
10 print "\n# ------------------------------------------------";
11 $fv = Finance::FVofAnnuity($monthly,$rate,$time);
12 printf "\n For a monthly %8.2f at a rate of %%%6.2f for %d periods",
13 $monthly, $rate, $time;
14 printf "\n you get a future value of %8.2f ", $fv;
15
16 $fv *= 1.1; # allow 10 % gain in the house value.
17
18 $mo = Finance::AnnuityOfFV($fv,$rate,$time);
19
20 printf "\n To get 10 percent more at the end, i.e. %8.2f",$fv;
21 printf "\n you need a monthly payment value of %8.2f",$mo,$fv;
22
23 print "\n# ------------------------------------------------ \n";

Here is sample input and output for this function:

$ testme
# ------------------------------------------------
For a monthly 400.00 at a rate of % 0.20 for 36 periods
you get a future value of 1415603.75
To get 10 percent more at the end, i.e. 1557164.12
you need a monthly payment value of 440.00
# ------------------------------------------------
Multiple Inheritance

Modules implement classes in a Perl program that uses the object-oriented features of Perl. Included in object-oriented features is the concept of inheritance . (You'll learn more on the object-oriented features of Perl in Chapter 5 , "Object-Oriented Programming in Perl .") Inheritance means the process with which a module inherits the functions from its base classes. A module that is nested within another module inherits its parent modules' functions. So inheritance in Perl is accomplished with the :: construct. Here's the basic syntax:

SuperClass::NextSubClass:: ... ::ThisClass.

The file for these is stored in ./SuperClass/NextSubClass/ . Each double colon indicates a lower-level directory in which to look for the module. Each module, in turn, declares itself as a package with statements like the following:

package SuperClass::NextSubClass;
package SuperClass::NextSubClass::EvenLower;

For example, say that you really want to create a Money class with two subclasses, Stocks and Finance . Here's how to structure the hierarchy, assuming you are in the /usr/lib/perl5 directory:

  1. Create a Money directory under the /usr/lib/perl5 directory.
  2. Copy the existing Finance.pm file into the Money subdirectory.
  3. Create the new Stocks.pm file in the Money subdirectory.
  4. Edit the Finance.pm file to use the line package Money::Finance instead of package Finance; .
  5. Edit scripts to use Money::Finance as the subroutine prefix instead of Finance:: .
  6. Create a Money.pm file in the /usr/lib/perl5 directory.

The Perl script that gets the moving average for a series of numbers is presented in Listing 4.7.


Listing 4.7. Using inheriting modules.
1 #!/usr/bin/perl -w
2 $aa = 'pwd';
3 $aa .= "/Money";
4 push(@Inc,$aa);
5 use Money::Finance;
6 @values = ( 12,22,23,24,21,23,24,23,23,21,29,27,26,28 );
7 @mv = (0);
8 $size = scalar(@values);
9 print "\n Values to work with = { @values } \n";
10 print " Number of values = $size \n";
11 # ----------------------------------------------------------------
12 # Calculate the average of the above function
13 # ----------------------------------------------------------------
14 $ave = Money::Finance::getLastAverage(5,$size,@values);
15 print "\n Average of last 5 days = $ave \n";
16 Money::Finance::getMovingAve(5,$size,@values,@mv);
17 # foreach $i (@values) {
18 # print "\n Moving with 5 days window = $mv[$i] \n";
19 # }
20 print "\n Moving Average with 5 days window = \n { @mv } \n";

Lines 2 through 4 add the path to the Money subdirectory. The use statement in line 5 now addresses the Finance.pm file in the ./Money subdirectory. The calls to the functions within Finance.pm are now called with the prefix Money::Finance:: instead of Finance:: . Therefore, a new subdirectory is shown via the :: symbol when Perl is searching for modules to load.

The Money.pm file is not required. Even so, you should create a template for future use. Actually, the file would be required to put any special requirements for initialization that the entire hierarchy of modules uses. The code for initialization is placed in the BEGIN() function. The sample Money.pm file is shown in Listing 4.8.


Listing 4.8. The superclass module for Finance.pm .
1 package Money;
2 require Exporter;
3
4 BEGIN {
5 printf "\n Hello! Zipping into existence for you\n";
6 }
7 1;

To see the line of output from the printf statement in line 5, you have to insert the following commands at the beginning of your Perl script:

use Money;
use Money::Finance;

To use the functions in the Stocks.pm module, you use this line:

use Money::Stocks;

The Stocks.pm file appears in the Money subdirectory and is defined in the same format as the Finance.pm file, with the exceptions that use Stocks is used instead of use Finance and the set of functions to export is different.

The Perl Module Libraries

A number of modules are included in the Perl distribution. Check the /usr/lib/perl5/lib directory for a complete listing after you install Perl. There are two kinds of modules you should know about and look for in your Perl 5 release, Pragmatic and Standard modules.

Pragmatic modules, which are also like pragmas in C compiler directives, tend to affect the compilation of your program. They are similar in operation to the preprocessor elements of a C program. Pragmas are locally scoped so that they can be turned off with the no command. Thus, the command

no POSIX ;

turns off the POSIX features in the script. These features can be turned back on with the use statement.

Standard modules bundled with the Perl package include several functioning packages of code for you to use. Refer to appendix B, "Perl Module Archives," for a complete list of these standard modules.

To find out all the .pm modules installed on your system, issue the following command. (If you get an error, add the /usr/lib/perl5 directory to your path.)

find /usr/lib/perl5 -name perl "*.pm" -print
Extension Modules

Extension modules are written in C (or a mixture of Perl and C) and are dynamically loaded into Perl if and when you need them. These types of modules for dynamic loading require support in the kernel. Solaris lets you use these modules. For a Linux machine, check the installation pages on how to upgrade to the ELF format binaries for your Linux kernel.

What Is CPAN?

The term CPAN (Comprehensive Perl Archive Network) refers to all the hosts containing copies of sets of data, documents, and Perl modules on the Net. To find out about the CPAN site nearest you, search on the keyword CPAN in search engines such as Yahoo!, AltaVista, or Magellan. A good place to start is the www.metronet.com site .

Summary

This chapter introduced you to Perl 5 modules and described what they have to offer. A more comprehensive list is found on the Internet via the addresses shown in the Web sites http://www.metronet.com and http://www.perl.com .

A Perl package is a set of Perl code that looks like a library file. A Perl module is a package that is defined in a library file of the same name. A module is designed to be reusable. You can do some type checking with Perl function prototypes to see whether parameters are being passed correctly. A module has to export its functions with the @EXPORT array and therefore requires the Exporter module. Modules are searched for in the directories listed in the @Inc array.

Obviously, there is a lot more to writing modules for Perl than what is shown in this chapter. The simple examples in this chapter show you how to get started with Perl modules. In the rest of the book I cover the modules and their features, so hang in there.

I cover Perl objects, classes, and related concepts in Chapter 5 .

[Sep 21, 2019] Writing PERL Modules - Tutorialspoint

Sep 21, 2019 | www.tutorialspoint.com

What are Packages?

The Package Statement
$i = 1; print "$i\n"; # Prints "1"
package foo;
$i = 2; print "$i\n"; # Prints "2"
package main;
print "$i\n"; # Prints "1"
$PACKAGE_NAME::VARIABLE_NAME

For Example:
$i = 1; print "$i\n"; # Prints "1"
package foo;
$i = 2; print "$i\n"; # Prints "2"
package main;
print "$i\n"; # Prints "1"

print "$foo::i\n"; # Prints "2"
BEGIN and END Blocks

You may define any number of code blocks named BEGIN and END which act as constructors and destructors respectively.

BEGIN { ... }
END { ... }
BEGIN { ... }
END { ... }
What are Perl Modules?

A Perl module is a reusable package defined in a library file whose name is the same as the name of the package (with a .pm on the end).

A Perl module file called "Foo.pm" might contain statements like this.

#!/usr/bin/perl

package Foo;
sub bar { 
   print "Hello $_[0]\n" 
}

sub blat { 
   print "World $_[0]\n" 
}
1;

Few noteable points about modules

The Require Function

A module can be loaded by calling the require function

#!/usr/bin/perl

require Foo;

Foo::bar( "a" );
Foo::blat( "b" );

Notice above that the subroutine names must be fully qualified (because they are isolated in their own package)

It would be nice to enable the functions bar and blat to be imported into our own namespace so we wouldn't have to use the Foo:: qualifier.

The Use Function

A module can be loaded by calling the use function

#!/usr/bin/perl

use Foo;

bar( "a" );
blat( "b" );

Notice that we didn't have to fully qualify the package's function names?

The use function will export a list of symbols from a module given a few added statements inside a module

require Exporter;
@ISA = qw(Exporter);

Then, provide a list of symbols (scalars, lists, hashes, subroutines, etc) by filling the list variable named @EXPORT : For Example

package Module;

require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(bar blat);

sub bar { print "Hello $_[0]\n" }
sub blat { print "World $_[0]\n" }
sub splat { print "Not $_[0]\n" }  # Not exported!

1;
Create the Perl Module Tree

When you are ready to ship your PERL module then there is standard way of creating a Perl Module Tree. This is done using h2xs utility. This utility comes alongwith PERL. Here is the syntax to use h2xs

$h2xs -AX -n  Module Name

# For example, if your module is available in Person.pm file
$h2xs -AX -n Person

This will produce following result
Writing Person/lib/Person.pm
Writing Person/Makefile.PL
Writing Person/README
Writing Person/t/Person.t
Writing Person/Changes
Writing Person/MANIFEST

Here is the descritpion of these options

So above command creates the following structure inside Person directory. Actual result is shown above.

So finally you tar this directory structure into a file Person.tar and you can ship it. You would have to update README file with the proper instructions. You can provide some test examples files in t directory.

Installing Perl Module

Installing a Perl Module is very easy. Use the following sequence to install any Perl Module.

perl Makefile.PL
make
make install

The Perl interpreter has a list of directories in which it searches for modules (global array @INC)

[Nov 22, 2017] Perl modules

Nov 17, 2017 | perlmonks.com

Discipulus (Monsignor) on Nov 16, 2017 at 09:04 UTC

Re: perl modules

Hello codestroman and welcome to the monastery and to the wonderful world of Perl!

First of all, please, add <c> code tags </c> around your code and output.

Then be sure to have read the standard documentation: perlmod and perlnewmod

Infact a basic Perl module define a package and use Exporter to export functions in the using Perl program.

In my homenode i've collected a lot of links on about module creation

L*

Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

thanos1983 (Priest) on Nov 16, 2017 at 09:17 UTC

Re: perl modules

Hello codestroman

Just to add a minor suggestion here, to the full cover reply of fellow monk Discipulus . It will assist you a lot also to read Simple Module Tutorial

Update: Direct answer to your question can be found here How to add a relative directory to @INC with multiple possible solutions. I would strongly recommend to go through all the articles that all monks proposed.

Hope this helps, BR.

Seeking for Perl wisdom...on the process of learning...not there...yet!

hippo (Abbot) on Nov 16, 2017 at 09:21 UTC

Re: perl modules (Can't locate in @INC)
PLEASE HELP!!

This is a monastery - a place of quite contemplation. The louder you shout the less wisdom shall you receive.

The error message Can't locate dog.pm in @INC is pretty explicit. Either your module file is not called dog.pm in which case, change it or else your file dog.pm is not in any of the directories listed in @INC in which case either move it to one of those directories or else change @INC with use lib .

I also see, despite the lack of formatting in your post that your module doesn't use any namespace. You should probably address that. Perhaps a solid read through Simple Module Tutorial would be a good idea?

Anonymous Monk on Nov 16, 2017 at 09:07 UTC

Re: perl modules

use an absolute pathname in use lib

Anonymous Monk on Nov 16, 2017 at 15:16 UTC

Re: perl modules

Welcome to the language ... and, to the Monastery. The "simple module tutorial" listed above is a very good place to start. Like all languages of its kind, Perl looks at runtime for external modules in a prescribed list of places, in a specified order. You can affect this in several ways, as the tutorials describe. Please read them carefully.

In the Perl(-5) language, this list is stored in a pre-defined array variable called @INC and it is populated from a variety of sources: a base-list that is compiled directly into the Perl interpreter, the PERL5LIB environment-variable, use lib statements, and even direct modification of the variable itself. Perl searches this list from beginning to end and processes (only) the first matching file that it finds.

(Note that, in Perl, the use statement is actually a pragma, or declaration to the compiler, and as such it has many "uses" and a somewhat complicated syntax.)

Corion (Pope) on Nov 16, 2017 at 15:23 UTC

Re^2: perl modules


by Corion (Pope) on Nov 16, 2017 at 15:23 UTC

(Note that, in Perl, the use statement is actually a pragma, or declaration to the compiler, and as such it has many "uses" and a somewhat complicated syntax.)

Please no.

The word "pragma" has a special meaning in Perl, and it is highly confusing to claim that a Perl "keyword" would be a "pragma". use certainly is a keyword and nothing else.

If you mean to say something different, please describe in more words what you want to say.

[Nov 16, 2017] Namespaces and modules

Feb 09, 2015 | perlmonks.com

on Feb 09, 2015 at 13:21 UTC ( # 1116049 =

Greetings, Ô wise monks !

I come to you because of a mystery I'
d like to unravel: The module import code doesn'
t work as I expected. So, as I'
m thinking that it probably is a problem with my chair-keyboard interface, rather than with the language, I need your help.

So, there are these modules I have, the first one goes like this:

use utf8;
use Date::Manip;
use LogsMarcoPolo;
package LibOutils;
BEGIN { require Exporter;
# set the version for version checking our $VERSION = 1.00;
# Inherit from Exporter to export functions and variables our @ISA = qw(Exporter);
# Functions and variables which are exported by default our @EXPORT = qw(getDateDuJour getHeureActuelle getInfosSemaine ge tTailleRepertoire getInfosPartition getHashInfosContenuRepertoire dor mir);
# Functions and variables which can be optionally exported our @EXPORT_OK = qw();
} # Under this line are definitions of local variables, and the subs.
[download]

I also have another module, which goes like that:

use utf8;
use strict;
use warnings;
use Cwd;
# Module "
CORE"
use Encode;
use LibOutils qw(getHeureActuelle);
package LogsMarcoPolo;
BEGIN { require Exporter;
# set the version for version checking our $VERSION = 1.00;
# Inherit from Exporter to export functions and variables our @ISA = qw(Exporter);
# Functions and variables which are exported by default our @EXPORT = qw(setNomProgramme ouvreFichierPourLog assigneFluxPo urLog pushFlux popFlux init printAndLog);
# Functions and variables which can be optionally exported our @EXPORT_OK = qw();
} # Here are other definitions of variables and subs, which I removed fo r the sake of clarity sub init { my ($nomDuProgramme, $pathLogGeneral, $pathLogErreurs) = @_;
my $date = LibOutils::getDateDuJour();
# La date de l'
appel à init() my $time = LibOutils::getHeureActuelle();
# L'
heure de l'
appel à init() $nomProgramme = $nomDuProgramme;
# Ouverture du flux pour STDOUT: my $stdout = assigneFluxPourLog(*STDOUT);
# On l'
ajoute à la liste de flux '
OUT'
: pushFlux('
OUT'
, $stdout);
# Ouverture du flux pour STDERR: my $stderr = assigneFluxPourLog(*STDERR);
# On l'
ajoute à la liste de flux '
ERR'
, et à la liste '
DUO'
: pushFlux('
ERR'
, $stderr);
pushFlux('
DUO'
, $stderr);
if (defined $pathLogGeneral) { my $plg = $pathLogGeneral;
$plg =~ s/<
DATE>
/$date/g;
$plg =~ s/<
TIME>
/$time/g;
my $logG = ouvreFichierPourLog($plg);
pushFlux('
OUT'
, $logG);
pushFlux('
DUO'
, $logG);
} if (defined $pathLogErreurs) { my $ple = $pathLogErreurs;
$ple =~ s/<
DATE>
/$date/g;
$ple =~ s/<
TIME>
/$time/g;
my $logE = ouvreFichierPourLog($ple);
pushFlux('
ERR'
, $logE);
pushFlux('
DUO'
, $logE);
} }
[download]

Now, look at the second module: When, in the "
init"
sub, I call the getDateDuJour() and getHeureActuelle() functions with an explicit namespace, it works fine.

If I remove the prefix, it doesn'
t work, even for the function whose name I put in the "
qw(...)"
chain after the use.

Would a fellow monk know why ?

choroba (Bishop) on Feb 09, 2015 at 13:24 UTC

Re: Namespaces and modules

By putting package after the use clauses, you are importing all the functions to the "
main"
namespace, not into your package'
s namespace. Moving the package declaration up should help.

kzwix (Sexton) on Feb 09, 2015 at 13:34 UTC

Re^2: Namespaces and modules

by kzwix (Sexton) on Feb 09, 2015 at 13:34 UTC

I wonder, could it have something to do with loop-including ?

I mean, package "
LibOutils"
uses "
LogsMarcoPolo"
(for its logging system), but "
LogsMarcoPolo"
uses "
LibOutils"
for its dates and times.

Could that circular include be the origin of this bug ?

Anonymous Monk on Feb 09, 2015 at 14:18 UTC

Re^3: Namespaces and modules
by Anonymous Monk on Feb 09, 2015 at 14:18 UTC
I wonder, could it have something to do with loop-including ?

Circular dependencies don'
t automatically cause a problem, it also depends on what the module does in its body (which you haven'
t shown). If you think there is a problem, a short piece of example code that reproduces the problem would help, see http://sscce.org/

But first, did you try what choroba suggested ?

kzwix (Sexton) on Feb 09, 2015 at 15:04 UTC

Re^4: Namespaces and modules
by kzwix (Sexton) on Feb 09, 2015 at 15:04 UTC

Corion (Pope) on Feb 09, 2015 at 15:11 UTC

Re^5: Namespaces and modules
by Corion (Pope) on Feb 09, 2015 at 15:11 UTC

Anonymous Monk on Feb 09, 2015 at 15:59 UTC

Re^5: Namespaces and modules
by Anonymous Monk on Feb 09, 2015 at 15:59 UTC

Anonymous Monk on Feb 09, 2015 at 14:11 UTC

Re: Namespaces and modules
doesn'
t work as I expected ... it works fine ... it doesn'
t work

What are the exact error messages? What is the expected behavior vs. the behavior you'
re getting? See How do I post a question effectively?

[Nov 06, 2017] How to create a Perl Module for code reuse

Nov 06, 2017 | perlmaven.com

You may be creating more and more scripts for your systems, which need to use the same functions.

You already mastered the ancient art of copy-paste, but you are not satisfied with the result.

You probably know lots of Perl modules that allow you to use their functions and you also want to create one.

However, you don't know how to create such a module.

The module

  1. package My :: Math
  2. use strict
  3. use warnings
  4. use Exporter qw import );
  5. our @EXPORT_OK = qw add multiply );
  6. sub add
  7. my $x $y = @_
  8. return $x $y
  9. sub multiply
  10. my $x $y = @_
  11. return $x $y

Save this in somedir/lib/My/Math.pm (or somedir\lib\My\Math.pm on Windows).

The script
  1. #!/usr/bin/perl
  2. use strict
  3. use warnings
  4. use My :: Math qw add );
  5. print add 19 23 );

Save this in somedir/bin/app.pl (or somedir\bin\app.pl on Windows).

Now run perl somedir/bin/app.pl . (or perl somedir\bin\app.pl on Windows).

It is going to print an error like this:

Can't locate My/Math.pm in @INC (@INC contains:
...
...
...
BEGIN failed--compilation aborted at somedir/bin/app.pl line 9.
What is the problem?

In the script we loaded the module with the use keyword. Specifically with the use My::Math qw(add); line. This searches the directories listed in the built-in @INC variable looking for a subdirectory called My and in that subdirectory for a file called Math.pm .

The problem is that your .pm file is not in any of the standard directories of perl: it is not in any of the directories listed in @INC.

You could either move your module, or you could change @INC.

The former can be problematic, especially on systems where there is a strong separation between the system administrator and the user. For example on Unix and Linux system only the user "root" (the administrator) has write access to these directories. So in general it is easier and more correct to change @INC.

Change @INC from the command line

Before we try to load the module, we have to make sure the directory of the module is in the @INC array.

Try this:

perl -Isomedir/lib/ somedir/bin/app.pl .

This will print the answer: 42.

In this case, the -I flag of perl helped us add a directory path to @INC.

Change @INC from inside the script

Because we know that the "My" directory that holds our module is in a fixed place relative to the script, we have another possibility for changing the script:

  1. #!/usr/bin/perl
  2. use strict
  3. use warnings
  4. use File :: Basename qw dirname );
  5. use Cwd qw abs_path );
  6. use lib dirname dirname abs_path $0 '/lib'
  7. use My :: Math qw add );
  8. print add 19 23 );

and run it again with this command:

perl somedir/bin/app.pl .

Now it works.

Let's explain the change:

How to change @INC to point to a relative directory

This line: use lib dirname(dirname abs_path $0) . '/lib'; adds the relative lib directory to the beginning of @INC

$0 holds the name of the current script. abs_path() of Cwd returns the absolute path to the script.

Given a path to a file or to a directory the call to dirname() of File::Basename returns the directory part, except of the last part.

In our case $0 contains app.pl

abs_path($0) returns .../somedir/bin/app.pl

dirname(abs_path $0) returns .../somedir/bin

dirname( dirname abs_path $0) returns .../somedir

That's the root directory of our project.

dirname( dirname abs_path $0) . '/lib' then points to .../somedir/lib

So what we have there is basically

use lib '.../somedir/lib';

but without hard-coding the actual location of the whole tree.

The whole task of this call is to add the '.../somedir/lib' to be the first element of @INC.

Once that's done, the subsequent call to use My::Math qw(add); will find the 'My' directory in '.../somedir/lib' and the Math.pm in '.../somedir/lib/My'.

The advantage of this solution is that the user of the script does not have to remember to put the -I... on the command line.

There are other ways to change @INC for you use in other situations.

Explaining use

So as I wrote earlier, the use call will look for the My directory and the Math.pm file in it.

The first one it finds will be loaded into memory and the import function of My::Math will be called with the parameters after the name of the module. In our case import( qw(add) ) which is just the same as calling import( 'add' )

The explanation of the script

There is not much left to explain in the script. After the use statement is done calling the import function, we can just call the newly imported add function of the My::Math module. Just as if I declared the function in the same script.

What is more interesting is to see the parts of the module.

The explanation of the module

A module in Perl is a namespace in the file corresponding to that namespace. The package keyword creates the namespace. A module name My::Math maps to the file My/Math.pm. A module name A::B::C maps to the file A/B/C.pm somewhere in the directories listed in @INC.

As you recall, the use My::Math qw(add); statement in the script will load the module and then call the import function. Most people don't want to implement their own import function, so they load the Exporter module and import the 'import' function.

Yes, it is a bit confusing. The important thing to remember is that Exporter gives you the import.

That import function will look at the @EXPORT_OK array in your module and arrange for on-demand importing of the functions listed in this array.

OK, maybe I need to clarify: The module "exports" functions and the script "imports" them.

The last thing I need to mention is the 1; at the end of the module. Basically the use statement is executing the module and it needs to see some kind of a true statement there. It could be anything. Some people put there 42; , others, the really funny ones put "FALSE" there. After all every string with letters in it is considered to be true in Perl . That confuses about everyone. There are even people who put quotes from poems there.

"Famous last words."

That's actually nice, but might still confuse some people at first.

There are also two functions in the module. We decided to export both of them, but the user (the author of the script) wanted to import only one of the subroutines.

Conclusion

Aside from a few lines that I explained above, it is quite simple to create a Perl module. Of course there are other things you might want to learn about modules that will appear in other articles, but there is nothing stopping you now from moving some common functions into a module.

Maybe one more advice on how to call your module:

Naming of modules

It is highly recommended to use capital letter as the first letter of every part in the module name and lower case for the rest of the letters. It is also recommended to use a namespace several levels deep.

If you work in a company called Abc, I'd recommend preceding all the modules with the Abc:: namespace. If within the company the project is called Xyz, then all its modules should be in Abc::Xyz::.

So if you have a module dealing with configuration you might call the package Abc::Xyz::Config which indicates the file .../projectdir/lib/Abc/Xyz/Config.pm

Please avoid calling it just Config.pm. That will confuse both Perl (that comes with its own Config.pm) and you.

Recommended Links

Perl module - Wikipedia, the free encyclopedia

Perl Module Mechanics by Steven McDougall 2007 March 02

This page describes the mechanics of creating, compiling, releasing and maintaining Perl modules.

This is not a reference manual. Rather, it is a running account of how to do these things. More to the point, it is an account of how I do these things. Accordingly

See also Perl Module Anatomy by Steven McDougall. Short and not very informative notes about the contents of the .pm file

IBM developerWorks: Parsing with Perl modules(Apr 30, 2000)

The very very short tutorial about modules in Perl [ New: 06/16/99 ] Mark-Jason Dominus a really short tutorial about Perl Modules.

The Seven Useful Uses of local

perltoot - Tom Christiansen's object-oriented tutorial for perl

modules

Perl for Newbies - Part 3 - The Perl Beginners' Site

Perl Module Primer By Dan Ragle

Perl module - Wikipedia, the free encyclopedia

Installing Your Own Perl Modules

Creating (and Maintaining) Perl Modules

Amazon.com- Perl Modules- Eric Foster-Johnson- Books

Perl Module Review- Class--Trait - O'Reilly ONLamp Blog

O'Reilly Perl Center

Writing Apache Modules with Perl and C - by Lincoln D Stein - 744 pages

Learning Perl Objects References and Modules - by Randal L Schwartz - 228 pages

Reference

Man Pages:
perlmod Perl modules (packages and symbol tables)
perlref Perl references and nested data structures
perlobj Perl objects
perltoot Tom's object-oriented tutorial for perl
perlbot Bag'o Object Tricks (advanced stuff)

Websites:

genome-www.stanford.edu/perlOOP A little collection I put together as I was learning Object-oriented Perl programming. See especially the examples page.
www.perl.com/CPAN/CPAN.html CPAN homepage
search.cpan.org Search CPAN for a module by author, category, or module name
bioperl.org The Bioperl project - modules for bioinformatics


Etc

Society

Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers :   Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy

Quotes

War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard Shaw : Mark Twain Quotes

Bulletin:

Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 :  Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method  : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law

History:

Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Hater’s Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor

The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D


Copyright © 1996-2021 by Softpanorama Society. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.

This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to to buy a cup of coffee for authors of this site

Disclaimer:

The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.

Last modified: October 11, 2020