How do you print exported module constants in Perl? - perl

I want to define some constants in one package and then use them in another package, but I don't seem to be doing this right! At first shot I was getting
Bareword "FAVORITE_COLOR" not allowed while "strict subs" in use at ...
I guess it was because I wasn't using the base path for my package in the lib() function,
Module
My/Colors.pm
package My::Colors;
BEGIN {
use Exporter;
our($VERSION, #ISA, #EXPORT, #EXPORT_OK, %EXPORT_TAGS);
$VERSION = 1.00;
#ISA = qw(Exporter);
#EXPORT = qw( );
#EXPORT_OK = qw( FAVORITE_COLOR DISLIKED_COLOR );
%EXPORT_TAGS = ( 'all' => [ #EXPORT, #EXPORT_OK ], 'const' => [ 'FAVORITE_COLOR', 'DISLIKED_COLOR'] );
}
our #EXPORT_OK;
use lib qw( /home/dev );
use Carp;
use constant {
DISLIKED_COLOR => "green",
FAVORITE_COLOR => "red"
};
sub new {
my($class, %args) = #_;
my $self = bless({}, $class);
my $target = exists $args{target} ? $args{target} : "new";
$self->{target} = $target;
return $self;
}
1;
Module that includes exported constants
color_driver.plx
#!/usr/bin/perl -w
use warnings;
use strict;
use diagnostics;
use lib qw( /home/dev/My );
use Colors;
use Colors qw(:const);
sub main{
my $color = new Colors;
print "Color is",FAVORITE_COLOR;
}
main();
any idea what I'm doing wrong?
When I remove strict the constant doesnt translate to its value =/
Updated
Unfortunately now perl is complaining that it can't find new sub
Can't locate object method "new" via package "Colors" (perhaps you
forgot to
load "Colors"?) at color_driver.plx line 15 (#1)

In the module:
package My::Colors;
In the script:
use lib qw( /home/dev/My );
use Colors qw(:const);
my $color = new Colors;
Either change those lines of the module to
package Colors;
or change those lines of the script to
use lib qw( /home/dev );
use My::Colors qw(:const);
my $color = new My::Colors;
use Colors qw( :const );
is almost identical to
BEGIN {
require Colors;
Colors->import(qw( :const ));
}
You are telling Perl to look in the Colors package/namespace for import (and new), but the module populates the package/namespace My::Colors.

Related

How to save the content of global variable to a lexical variables in Perl and access it from sub

I'm trying to save the content of a our global variable declared in the main script, to a my lexical variable in a module.
main.pl
use strict;
use warnings;
use module;
our $global = "Hello";
function();
module.pm
package module;
use strict;
use warnings;
use Exporter 'import';
our #EXPORT = qw( function );
# some needed initialization & definition before subs
my $var = $main::global;
sub function {
print $var,"\n";
}
1;
I'm facing : Use of uninitialized value $var error
Even when i try to do a print just under the assignment, it doesn't work !
Thanks.
finally i got what i want by creating a module which contain all the global variable i want. and use it everywhere when needed.
it look like this
package Globals;
use Exporter 'import';
our #EXPORT = qw( $VERSION $DEV_EMAIL $BASEDIR $CURRENT_PROJECT );
our $VERSION = "0.0.1";
our $DEV_EMAIL = "FOO#BAR.COM";
our $BASEDIR = "./Projects/";
our $CURRENT_PROJECT = '';
1;
OtherPackage.pm
package OtherPackage
use Globals;
my $var = $VERSION
# do something with $var
print $var;
1;

Perl Module Creation & Usage - Undefined subroutine

I am trying to create & use modules in a new script I'm doing but I'm not familiar with modules yet.
I've been following some tutorials, and even if I have the "almost" exact same code as in the tutorial, it doesn't work and when I run my test-script I get the following error:
Undefined subroutine &main::func1 called at ../../bin/fftg.pl line 21.
Here is my main script :
#!/usr/bin/perl
# ......
# comments here
# ......
use strict;
use warnings;
use File::Basename qw(dirname);
use Cwd qw(abs_path);
use lib dirname(dirname abs_path $0) . '/lib';
use FFTG::PID qw(:DEFAULT);
print func1(10,20);
and here is the module, created as file lib/FFTG/PID.pm :
package PID;
use strict;
use warnings;
use Exporter;
our $VERSION = 1.00;
our #ISA = qw(Exporter);
our #EXPORT = qw(&func1 &func2); # I tried all lines without &
our #EXPORT_OK = qw(&func1 &func2); # I tried all lines without &
our %EXPORT_TAGS = ( DEFAULT => [qw(&func1)],
Both => [qw(&func1 &func2)]);
sub func1
{
my ($x, $y) = #_;
return $x + $y;
}
sub func2
{
return "tata\n";
}
1;
what am I doing wrong please ?
I tried to load the thing using :
use FFTG::PID qw(:DEFAULT);
use FFTG::PID;
use FFTG::PID qw(funct1);
use FFTG::PID qw(&funct1);
nothing works (same error)
I also tried to modify the module, modifying these lines removing or adding the & :
our #EXPORT = qw(func1 func2);
our #EXPORT_OK = qw(func1 func2);
same problem
any hints ?
my folders & files are :
MIF/root#sm1p0003vmo /wminfs/mc/projects/FFTGv2: pwd
/wminfs/mc/projects/FFTGv2
MIF/root#sm1p0003vmo /wminfs/mc/projects/FFTGv2: ls -al bin/fftg.pl
-rwxr-x--- 1 root root 545 May 18 09:49 bin/fftg.pl
MIF/root#sm1p0003vmo /wminfs/mc/projects/FFTGv2: ls -al lib/FFTG/PID.pm
-rw-r----- 1 root root 344 May 18 09:37 lib/FFTG/PID.pm
MIF/root#sm1p0003vmo /wminfs/mc/projects/FFTGv2:
thanks
regards,
There are a few errors, and a few things that can be done better.
The module name needs to match its (relative) location, so: package FFTG::PID;
There can be no & when listing subroutines for EXPORTs in the module; those should be names and the & isn't a part of the name. From use pragma (my emphasis)
Imports some semantics into the current package from the named module
All-caps names are a risky idea as they may be taken, and DEFAULT cannot be used here
It is generally a good advice to use #EXPORT_OK, and not #EXPORT.
Finally, the line that sets up lib is asking for trouble. Use FindBin.
Package lib/FFTG/PID.pm
package FFTG::PID;
use strict;
use warnings;
use Exporter qw(import);
our $VERSION = 1.00;
our #EXPORT_OK = qw(func1 func2);
our %EXPORT_TAGS = (
default => [ qw(func1) ],
both => [ qw(func1 func2) ]
);
sub func1
{
my ($x, $y) = #_;
return $x + $y;
}
sub func2
{
return "tata\n";
}
1;
where I've also replaced the explicit setup of #ISA with the Exporter'simport method.
The main program
use strict;
use warnings;
use feature qw(say);
use FindBin qw($RealBin);
use lib "$RealBin/lib";
use FFTG::PID qw(:default);
say func1(10,20);
It prints a line with 30.

How to conditionally import functions from another module and export them to the local namespace

Assume I have a module named Local that exports a subroutine subLocal via the %EXPORT_TAGS interface.
This module is closely related to another module named Remote that defines subroutines the user of Local might want to import.
There are two requirements I would like to have:
Module Local should import the subroutines defined in Remote only if the user of module Local is importing a subroutine defined in Remote (either by explicitly naming the export or by using a specific export tag)
When a subroutine from Remote is imported into Local, the user of module Local should be able to refer to that subroutine as if it is in his local namespace (the same behavior you would get when referring to a subroutine defined in Local).
I've only found a (hacky) solution for req. 2 by adding an entry in the symbol table, but this always occurs -- regardless if the user of Local actually needs the subroutines in Remote. According to perldoc, this pointlessly "pollutes" the namespace.
So at what point during compilation or runtime should I be trying to import the subroutines from Remote? And how do I actually import them in such a way that they appear in the local namespace?
This is my current approach. Module Local:
package Local;
use strict;
use warnings;
BEGIN
{
require Exporter;
our #ISA = qw| Exporter |;
our #EXPORT_LOCAL = qw| subLocal |;
our #EXPORT_REMOTE = qw| subRemote |;
our #EXPORT_OK = ( #EXPORT_LOCAL, #EXPORT_REMOTE );
our %EXPORT_TAGS =
( all => \#EXPORT_OK, local => \#EXPORT_LOCAL, remote => \#EXPORT_REMOTE );
*subRemote = \&Remote::subRemote; # <-- can I do this conditionally somewhere?
# <-- and is there a better way to put this function in the user's local namespace?
}
use Remote; # <-- can I do this conditionally somewhere?
sub subLocal { return "(local)" }
1;
And module Remote:
package Remote;
use strict;
use warnings;
BEGIN
{
require Exporter;
our #ISA = qw| Exporter |;
our #EXPORT_REMOTE = qw| subRemote |;
our #EXPORT_OK = ( #EXPORT_REMOTE );
our %EXPORT_TAGS =
( all => \#EXPORT_OK, remote => \#EXPORT_REMOTE );
}
sub subRemote { return "(remote)" }
1;
Why would you want to import subs into Local subs that Local is asked to export? Might as well place them directly into the right module instead of Local!
Either way, you won't be able to use (just) Exporter. There might an existing alternative to Exporter you could use. Otherwise, you'll need to write your own import.
Local.pm:
package Local;
use strict;
use warnings;
use Carp qw( croak );
use Exporter qw( );
use Import::Into qw( );
use Remote qw( );
my #export_ok_local = qw( subLocal );
my #export_ok_remote = qw( subRemote );
my #export_ok_all = ( #export_ok_local, #export_ok_remote );
my %export_tags = (
':ALL' => \#export_ok_all,
':DEFAULT' => [],
':local' => \#export_ok_local,
':remote' => \#export_ok_remote,
);
our #EXPORT_OK = #export_ok_local;
sub import {
my $class = shift;
my $target = caller;
my #imports =
map {
!/^:/
? $_
: !$export_tags{$_}
? croak("\"$_\" isn't a recognized tag")
: #{ $export_tags{$_} }
}
#_;
my %imports = map { $_ => 1 } #imports;
my #local = grep { $imports{$_} } #export_ok_local;
my #remote = grep { $imports{$_} } #export_ok_remote;
delete #imports{ #local, #remote };
my #unknown = keys(%imports);
croak("Not exported by ".__PACKAGE__.": #unknown\n") if #unknown;
Remote->import::into($target, #remote);
#_ = ( $class, #local );
goto &Exporter::import;
}
sub subLocal { print("subLocal\n"); }
1;
Remote.pm:
package Remote;
use strict;
use warnings;
use Exporter qw( import );
our #EXPORT_OK = qw( subRemote );
sub subRemote { print("subRemote\n"); }
1;
Test:
$ perl -e'
use Local qw( subLocal subRemote );
subLocal();
subRemote();
'
subLocal
subRemote
$ perl -e'
use Local qw( :ALL );
subLocal();
subRemote();
'
subLocal
subRemote
It's far simpler to simply import everything you want to export.
package Local;
use strict;
use warnings;
use Exporter qw( import );
my ( #EXPORT_LOCAL, #EXPORT_REMOTE );
BEGIN {
#EXPORT_LOCAL = qw| subLocal |;
#EXPORT_REMOTE = qw| subRemote |;
our #EXPORT_OK = ( #EXPORT_LOCAL, #EXPORT_REMOTE );
our %EXPORT_TAGS = (
ALL => \#EXPORT_OK,
local => \#EXPORT_LOCAL,
remote => \#EXPORT_REMOTE,
);
}
use Remote #EXPORT_REMOTE;
sub subLocal { ... }
1;
To be honest I think that the confusion you will create by messing with import is probably more of a problem than the namespace pollution in the first place, which is only an issue if you choose identifiers that clash with the imported ones
Here's an example using object-oriented design, which doesn't use import at all and there is zero namespace pollution. You don't even have to say in the main program which methods you will use
Remote.pm
use 5.010;
package Remote;
sub new {
my $class = shift;
my $self = bless {}, $class;
}
sub subRemote {
say "I am subRemote";
}
1;
Local.pm
use 5.010;
package Local;
use base 'Remote';
sub new {
my $class = shift;
my $self = $class->SUPER::new(#_);
}
sub subLocal {
say "I am subLocal";
}
1;
main.pl
use 5.010;
use Local;
my $obj = Local->new;
$obj->subLocal;
$obj->subRemote;
output
I am subLocal
I am subRemote
I take the question to be: That the caller of Local can require subRemote in its import list, but if it doesn't then the symbol isn't pushed into the caller's namespace.
I also assume that Local should not import from Remote at all unless the caller of Local requires some of Remote's subs in its import list.
Then write your own sub import. The list supplied by the caller are arguments passed to import, following the first argument which is __PACKAGE__ (in this case Local).
Then in your import you can check whether subRemote is asked for. If it is, require the package where it is defined and push its sub's full name to the caller's symbol table, otherwise not. You can establish and check any other conditions you may need.
This way Local loads Remote only if the caller of Local requires a sub from Remote.
An example for the above description
Local.pm
package Local;
use warnings;
use strict;
use Exporter qw();
our #EXPORT_OK = qw(subLocal subRemote);
sub import {
my $class = shift;
my $re = qr/^(?:subRemote|other)/;
my #local_exports = grep { !/$re/ } #_;
my #remote_exports = grep { /$re/ } #_; # check both
if (#remote_exports) {
no strict 'refs';
require Remote;
foreach my $export (#remote_exports)
{
my $to_caller = caller() . '::' . $export;
*{ $to_caller } = \&{ 'Remote::' . $export };
}
}
#_ = ($class, #local_exports); # set up #_ for goto
goto &Exporter::import; # switch to Exporter::import
}
sub subLocal { print "subLocal() in ", __PACKAGE__, "\n" }
1;
The references to subs from Remote that are asked for are written to the caller's symbol table. Then our import is swapped by Exporter::import for exporting the rest of the symbols, from Local. For a note on goto see this for example. A few things are left out, firstly checks of received import lists.
There are no surprises with main and Remote
main.pl
use warnings;
use strict;
use Local qw(subLocal subRemote);
subLocal();
subRemote();
Remote.pm
package Remote;
use warnings;
use strict;
use Exporter qw(import);
our #EXPORT_OK = qw(subRemote);
sub subRemote { print "subRemote() in ", __PACKAGE__, "\n" }
with the output
subLocal() in Local
subRemote() in Remote
This accomplishes what is asked but it has to deal with rather specific details.

Why don't functions from package A get imported into package B when they recursively call each other?

I'm trying to use two packages and call functions from one to other, but I've got this error:
Undefined subroutine &module2::method_1_2 called at module2.pm line 20.
Is there any way to call functions from one package to the other one without getting this error?
Thanks in advance.
xabi
exec error:
./test.pl
method_1_1
method_2_1
method_2_2
Undefined subroutine &module2::method_1_2 called at module2.pm line 20.
Sample code (test.pl):
#!/usr/bin/perl
use strict;
use module1;
use module2;
method_1_1();
method_2_2();
module1.pm
package module1;
use strict;
use module2;
require Exporter;
use vars qw(#ISA #EXPORT);
#ISA = qw(Exporter);
#EXPORT = qw( method_1_1 method_1_2 );
sub method_1_1
{
print "method_1_1\n";
method_2_1();
}
sub method_1_2
{
print "method_1_2\n";
}
1;
module2.pm:
package module2;
use strict;
use module1;
require Exporter;
use vars qw(#ISA #EXPORT);
#ISA = qw(Exporter);
#EXPORT = qw( method_2_1 method_2_2 );
sub method_2_1
{
print "method_2_1\n";
}
sub method_2_2
{
print "method_2_2\n";
method_1_2();
}
1;
The problem is that the very first thing module1 does is to use module2. That means all of module2 is read and executed while module1 is still compiling.
The next thing to happen is that module2 does use module1. Because module1 has been found and put into %INC Perl doesn't execute it again, and just does module1->import to fetch the exported symbols.
But of course module1 has in fact barely started compiling, and #module1::EXPORT doesn't even exist, never mind about its two subroutines. That makes Exporter import nothing at all into module2, so when it comes to make the call method_1_2() it knows nothing about it.
The cleanest way to fix this is to do the import after the compilation (including all the use statements and BEGIN blocks) but before runtime. Perl's INIT block is ideal for this, and we can get the code working by changing the modules to the form below. I have shown only module2 here, as the pattern of calls means this is all that's needed to fix this particular problem, but the general case needs the equivalent change to all cooperating modules.
package module2;
use strict;
use warnings;
use module1;
INIT { module1->import }
use base 'Exporter';
our #EXPORT = qw( method_2_1 method_2_2 );
sub method_2_1 {
print "method_2_1\n";
}
sub method_2_2 {
print "method_2_2\n";
method_1_2();
}
1;
The problem is that you assign to #EXPORT after it was already used. The following is copied from Mini-Tutorial: Mutual Use of Exporting Modules
[ The need to use this technique is a very strong indicator of a design flaw in your system, but I recognize that the resources are not always available to fix design flaws. ]
If ModA uses ModB, ModB uses ModA, and ModA or ModB imports symbols from the other, one needs to pay attention to code execution order. The best way I've found to avoid problems is to setup Exporter before loading any other module.
# ModA.pm
package ModA;
use strict;
use warnings;
use Exporter qw( import );
BEGIN { our #EXPORT_OK = qw( ... ); }
use This;
use ModB;
use That;
...
1;
# ModB.pm
package ModB;
use strict;
use warnings;
use Exporter qw( import );
BEGIN { our #EXPORT_OK = qw( ... ); }
use This;
use ModA;
use That;
...
1;
Interesting, I am not sure why method_1_2 isn't being exported into the module2 namespace, but you can get around this by explicitly referencing the package:
module1.pm
package module1;
use strict;
use warnings;
use module2 (); #don't import methods
use base 'Exporter';
our #EXPORT = qw( method_1_1 method_1_2 );
sub method_1_1
{
print "method_1_1\n";
module2::method_2_1();
}
sub method_1_2
{
print "method_1_2\n";
}
1;
module2.pm
package module2;
use strict;
use warnings;
use module1 (); #don't import methods
use base 'Exporter';
our #EXPORT = qw( method_2_1 method_2_2 );
sub method_2_1
{
print "method_2_1\n";
}
sub method_2_2
{
print "method_2_2\n";
module1::method_1_2();
}
1;
Okay, I think I see what is going on, but take this with a grain of salt. The use function is effectively a BEGIN block and BEGIN blocks run as soon as they are parsed, so the code looks like this in execution order.
perl starts parsing test.pl
it sees use module1; so it loads module1.pm and starts parsing it
perl sees use module2; in module1.pm so it loads module2.pm and starts parsing it
At this point, the functions in module1 do not yet exist, so they can't be imported
parsing continues
Something Borodin said tipped me off to the best solution: "#module1::EXPORT doesn't even exist". The problem here is that the #EXPORT variable doesn't exist. This can be fixed by putting it in a BEGIN block:
module1.pm
package module1;
use strict;
use warnings;
use base 'Exporter';
BEGIN {
our #EXPORT = qw( method_1_1 method_1_2 );
}
use module2;
sub method_1_1
{
print "method_1_1\n";
module2::method_2_1();
}
sub method_1_2
{
print "method_1_2\n";
}
1;
module2.pm
package module2;
use strict;
use warnings;
use base 'Exporter';
BEGIN {
our #EXPORT = qw( method_2_1 method_2_2 );
}
use module1;
sub method_2_1
{
print "method_2_1\n";
}
sub method_2_2
{
print "method_2_2\n";
method_1_2();
}
1;
IMPORTANT NOTE: I do not believe prototypes in module1 will be honored in any of these cases (and I don't see how they could be since module2 gets compiled before module1, so it can't know the prototypes exist). This is yet another argument to never use prototypes.

Perl library to avoid redefining an already defined function

I have two perl module files like :
is_date_holiday.pl :
use strict;
use warnings;
sub IsDateHoliday
{
...
}
1
calc_prev_working_date_mult.pl :
use strict;
use warnings;
require "is_date_holiday.pl"; # IsDateHoliday
sub CalcPrevWorkingDateMult
{
...
}
1
On using them both in a perl file like :
require "is_date_holiday.pl"; # IsDateHoliday
require "calc_prev_working_date_mult.pl" # CalcPrevWorkingDateMult
It complains that I am redefining the function IsDateHoliday
How can do an equivalent of #ifndef ?
You don't actually have modules, but you should.
IsDateHoliday.pm:
package IsDateHoliday;
use strict;
use warnings;
use Exporter qw( import );
our #EXPORT_OK = qw( IsDateHoliday );
our %EXPORT_TAGS = ( all => \#EXPORT_OK );
sub IsDateHoliday
{
...
}
1;
CalcPrevWorkingDateMult.pm:
package CalcPrevWorkingDateMult;
use strict;
use warnings;
use Exporter qw( import );
our #EXPORT_OK = qw( CalcPrevWorkingDateMult );
our %EXPORT_TAGS = ( all => \#EXPORT_OK );
use IsDateHoliday qw( :all );
sub CalcPrevWorkingDateMult
{
...
}
1;
main.pl:
use IsDateHoliday qw( :all );
use CalcPrevWorkingDateMult qw( :all );
Really you should create packages for these and then use them. That will eliminate the issues with redefining because you can then import what you need and use won't import stuff twice.
package IsDateHoliday;
use strict;
use warnings;
use Exporter;
our #ISA = qw(Exporter);
our #EXPORT = qw(IsDateHoliday);
sub IsDateHoliday {
#...
}
1; # not a typo, Perl needs modules to return true
Name the file "IsDateHoliday.pm" then when you need it:
use strict;
use lib '.'; # to include the local directory
use IsDateHoliday;
Same treatment for the other one.
Of course one might question why you don't just use Date::Calc from CPAN. (Might not have holidays but I'm sure something else on CPAN does!)
Although it'd be best to change to use over require, which will check to see if it's already been loaded first, if you really wanted to write C in perl, likely the closest to what you're trying to do would be to just set some variable, and check to see if exists, but you have to hide the subroutine definition in an eval.
# in the included file:
my $DateHolidayLoaded;
if ( !$DateHolidayLoaded ) {
eval {
sub IsDateHoliday { ... }
$DateHolidayLoaded = 1;
};
}
You can test for a function's existance, too, but you have to specify what namespace to use ... and in this case, it'd be 'main' :
if ( ! defined( main->can( 'IsDateHoliday' ) ) ) { require 'is_date_holiday.pl' }
But this will only work in the file doing the include; if you do this test in a file with the subroutine definition, it'll always be true.