using files other perl files in another perl file [duplicate] - perl

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
How do I include functions from another file in my Perl script?
I have a perl file suppose a.pl and I want to use a function from perl file b.pl. How do i do it

Turn b.pl into a module
Call it something descriptive like MyBModule (B is reserved by core).
rename the file to the something .pm like MyBModule.pm.
Add a package at the top, like package MyBModule;
Set a true return code on the package by making the last line 1;
You don't have to do anything else if you want to use your package name when calling the sub.
use MyBModule;
use strict;
use warnings;
MyBModule::sub1();
If you don't want to qualify it with the package name, read on...
Use Exporter.pm
Now configure Exporter.
Add the use Exporter; statement at the top of your module.
add a line our #EXPORT_OK = qw(sub1 sub2);
After you're done your module should look something like this
package MyBModule;
use strict;
use warnings;
use Exporter;
our #EXPORT_OK = qw(sub1 sub2);
sub sub1 { ... }
sub sub2 { ... }
Edit the caller
Make sure the library is in #INC, or the module in the current directory. If not append the directory to PERL5LIB.
Add a line like use MyBModule qw(sub1 sub2);
Read perldoc Exporter for more information
Your script should look like this afterward:
use strict;
use warnings;
use MyModuleB qw( sub1 sub2 );
It really isn't that hard, it takes about 15 seconds after you get used to doing it.

The best/conventional way is to keep all your functions in a Perl module file (.pm): See perlmod. This would require you to convert b.pl to a package. You would then access your module file (MyFuncs.pm) from a.pl with:
use MyFuncs;

Use the require and/or use functions.

Use the 'use' keyword to use functions from another module.
Example:
File a.pl:
use b;
f_in_b();
File b.pm:
sub f_in_b()
{
print "f_in_b\n";
}
1;
Important:
File b.pm must have the final 1;

Related

Perl: Use custom nested modules organised in nested sub-directories

I'm trying to figure out how to use nested modules organised in nested sub-directories with Perl. I mean, a test.pl program use a Foo module, and this in turn use another Bar module and so on... Let's put a little example, files could be organised in directories like that:
./test.pl
./lib/Foo.pm
./lib/common/Bar.pm
First thing that comes to mind is using the FindBin module in test.pl like that:
use FindBin;
use lib "$FindBin::RealBin/lib/.";
use Foo;
But if you want to do the same inside Foo to "use Bar", you need to include all the relative path from the test.pl program, including "/lib" segment. That means Foo needs to be aware of his relative path to the calling program. This forces kind of rigidity in the directories structure. For example, you can't simply copy&paste your custom modules wherever you want and call it. Besides, it needs to install the FindBin module in order to work.
In order to solve this issues, googling I found this solution: BEGIN solution that directly add paths to #INC. With this in mind, a solution could be:
./test.pl
#!/usr/bin/perl
use strict;
use warnings;
# Include lib in #INC
BEGIN {
use File::Basename;
my($filename, $dirs, $suffix) = fileparse(__FILE__);
my $common_path = $dirs."lib/.";
unshift(#main::INC, $common_path) ;
}
use Foo;
print "Inside: $Foo::message";
./lib/Foo.pm
package Foo;
# Include Common library
BEGIN {
use File::Basename;
my($filename, $dirs, $suffix) = fileparse(__FILE__);
$common_path = $dirs."common/.";
unshift(#main::INC, $common_path) ;
}
use Bar;
$message = " Foo > $Bar::message";
1;
./lib/common/Bar.pm
package Bar;
$message = "Bar";
1;
Executing ./test.pl should print:
Inside: Foo > Bar
You could nest any number of modules in their respective directories (I tested three levels), and what is better, copy&paste at whatever point of path without breaking functionality.
Nevertheless I dont't know if this method is advisable or have any disadvantages (I'm newby with perl). For example, is it advisable editing #INC directly like this?. is it advisable use the BEGIN code block for that?. Or, are there better ways to do this (allowing copy&paste directories at arbitrary points of the modules directories structure) so it works without touching code inside the modules?
Don't change #INC in modules. Leave that to the script.
use FindBin qw( $RealBin );
use lib "$RealBin/lib", "$RealBin/lib/common";
That means Foo needs to be aware of his relative path to the calling program.
If the libs are there for the script and each other, that's not a problem, and using use lib makes sense.
Otherwise, it's just a module for any script to use, and use lib shouldn't be used. Instead, it should be installed into standard installation directory (or a custom one specified by env var PERL5LIB).
By the way, you probably shouldn't put common inside of lib. This implies you can do use common::Bar;, which would be wrong.

Is the order of use of perl modules followed when evaluating subroutines?

I have a perl module that has a frequently used subroutine. For a specific set of scripts I need to override this subroutine so i created another module that has the new implementation. Does anyone know if the call order of the perl modules are always followed?
Ex.:
one.pm:
sub temp{ print “hi”; }
two.pm:
sub temp{ print “hello”; }
sample.pl:
use one; use two;
temp();
I have tested this and it prints “hello” as expected. But I wanted to make sure that this is always the case. Is the evaluation of imported modules in order all the time?
You should not write modules like that! Your just going to get into problems, including the one you're asking about. Any file loaded using use should have corresponding package. And they must end on a true value. (Your code doesn't compile because you failed to do so.)
Before I got on, let me mention that you should ALWAYS use use strict; use warnings;. Also note that lowercase module names are traditionally used for pragmas, modules that change how Perl itself behaves. It's a poor practice to use lowercase module names for other purposes.
Back to the point. At a minimum, you need the following:
One.pm:
package One;
use strict;
use warnings;
sub temp { ... }
1;
Two.pm:
package Two;
use strict;
use warnings;
sub temp { ... }
1;
The script would now look like this:
use strict;
use warnings;
use One qw( );
use Two qw( );
One::temp();
Two::temp();
And now you see that your problem is moot; there's no question about which sub is called.
But, what if you didn't want to prefix all the calls with One:: or Two::? We can do that!
One.pm:
package One;
use strict;
use warnings;
use Exporter qw( import );
our #EXPORT_OK = qw( temp );
sub temp { ... }
1;
Two.pm:
package Two;
use strict;
use warnings;
use Exporter qw( import );
our #EXPORT_OK = qw( temp );
sub temp { ... }
1;
The script would now look like this:
use strict;
use warnings;
use One qw( );
use Two qw( temp );
One::temp();
Two::temp();
temp(); # Calls Two::temp() because we imported temp from Two.
If you somehow did the following or equivalent, the last one would win out.
use One qw( temp );
use Two qw( temp );
That's why it's good to always list the subs you import. Don't use
use Foo; # Import default exports
Instead, use
use Foo qw( ); # Only import the listed exports. (None, in this case.)
If nothing else, it also makes it a lot easier to find subs and their documentation when maintaining the module.
The last one you compile wins, and use and require statements run in order from top to bottom (including any nesting inside modules that you include).
In this case, you have two module files, neither of which declare a package. Since they don't declare a package, they both use the default package main. Everything these modules define will show up in the main package.
Likewise, your program is also using the default package main, which is how is knows there is a temp subroutine. Since you loaded two.pm last, that's the definition that wins.
Now, let's fix up the code in your question because it doesn't actually work. Neither of those modules will load because neither returns a true value.
Both modules now have the same code because I can use the __FILE__ token to tell me which code ran:
one.pm:
sub temp { print 'From ' . __FILE__ }
1;
two.pm:
sub temp { print 'From ' . __FILE__ }
1;
temp.pl:
use lib qw(.);
use one;
use two;
temp();
Running this outputs the message from two.pm because that's the last one defined:
$ perl temp.pl
From two.pm
Run your program with warnings and you'll see there's a redefinition (which in this case is intentional):
$ perl -w temp.pl
Subroutine temp redefined at two.pm line 1.
From two.pm
The trick, then, is to ensure that your new code always comes last. One way to do this is to load the old module from the new one:
two.pm:
use one;
sub temp { print 'From ' . __FILE__ }
1;
I won't go any further with your example because I figure it's not your actual situation. I do write about these sorts of things in Effective Perl Programming though.
Yes. A use statement is equivalent to:
BEGIN { require Module; Module->import( LIST ); }
And Perl runs all compile time code (BEGIN blocks and use statements) in the order it appears (but before any runtime code is executed):
You may have multiple BEGIN blocks within a file (or eval'ed string); they will execute in order of definition.
What creates the subroutine in the current package is usually that module's import method, which will override any existing subroutines with those names at the time it runs.

Can't find exported subroutine in Perl

I have a module called Utilities.pm. It exports a subroutine called dummy_method.
package Foo::Utilities;
use strict;
use vars qw($VERSION #ISA #EXPORT #EXPORT_OK);
require Exporter;
#ISA = qw(Exporter);
#EXPORT = qw(dummy_method);
sub dummy_method {
# do things
}
I have a Perl script that uses the dummy_method subroutine:
use strict;
use warnings;
use Foo::Utilities qw('dummy_method');
my $foo = Foo::Utilities::dummy_method("foo");
print("$foo\n");
Executing that script throws an export error:
"dummy_method" is not exported by the Foo::Utilities module
Can't continue after import errors at /home/me/foo.pl line 3
BEGIN failed--compilation aborted at /home/me/foo.pl line 3.
I'm confused because I am explicitly exporting that subroutine with #EXPORT = qw(dummy_method);. How do I use dummy_method in another script?
Some people are obsessed with using qw for import lists, even if there is only one element. I think this makes others think this is a requirement, when it is just one way of making a list.
use Foo::Utilities qw('dummy_method');
says to import a method called 'dummy_method', not dummy_method, just like print qw('dummy_method') prints 'dummy_method', not dummy_method.
Try instead:
use Foo::Utilities 'dummy_method';
or, if you must:
use Foo::Utilities qw(dummy_method);
Though since you are exporting it by default, you could just do:
use Foo::Utilities;
Or, since you are calling it as Foo::Utilities::dummy_method, not even export it by default:
use Foo::Utilities ();
The code you have written, with the modification suggested by ysth, works correctly. The only remaining possibility that I can think of is that you have named or located your module incorrectly
use Foo::Utilities 'dummy_method'
will load a file called Foo/Utilities.pm where the Foo directory is in one of the paths in your #INC. It is a common error to omit the initial directories that must be in the path to the module, and you do say that your module is called just Utilities.pm
There must also be a Foo/Utilities.pm that behaves differently, otherwise the use statement would fail even to find the file
I have written your code in more modern Perl. This also works
Foo/Utilities.pm
package Foo::Utilities;
use strict;
use warnings 'all';
use Exporter 'import';
our #EXPORT = qw(dummy_method);
sub dummy_method {
print "dummy_method()\n";
'do things';
}
main.pl
use strict;
use warnings;
use Foo::Utilities 'dummy_method';
my $foo = dummy_method('foo');
print("$foo\n");
There is no need for using vars any more, and it has been better to import the import method from Exporter (instead of inheriting it) since Perl v5.8.7

Dealing with deep package names in perl and their exported constants and subroutines

This has probably been asked before, but I'm not sure what to search for. The problem is that I'm dealing with a package that is 4 directories deep and has a rather long name. Within the package are some exported constants that I want to use in main, but I don't want to use their fully qualified names, nor do I want to use their local name (the part after the last ::). For example.
use strict;
use warnings;
use Vendor::FirstPackage::SecondPackage::ThirdPackage qw(const_a);
# this is works, but I want to include the last package
my $x = const_a;
# this throws bareword error
my $y = ThirdPackage::const_a;
# this throws undefined subroutine
my $z = ThirdPackage::const_a();
Is there a way to access the constant via it's last package name?
use Package::Alias 'ThirdPackage' => 'Vendor::FirstPackage::SecondPackage::ThirdPackage';
But I'd recommend just using the fully qualified name.
You can create a package like this in your main script:
package ThirdPackage;
use strict;
use Vendor::FirstPackage::SecondPackage::ThirdPackage qw(const_a);
Then you should be able to access const_a as ThirdPackage::const_a. If you will put that package at the beginning of your main script, then main code should be separated with package main;
You could use Module::Load like this:
use strict;
use warnings;
use Module::Load qw(load_remote);
BEGIN {
load_remote 'ThirdPackage', 'Vendor::FirstPackage::SecondPackage::ThirdPackage', qw(const_a);
}
my $x = ThirdPackage::const_a;

Importing variable into Perl package

I'm writing a basic program whose core logic is split across several project-specific modules for cleanliness (keeping subroutines organised by their purpose in the program's logic).
Suddenly had trouble exposing an option from the main package in one of the modules, and using the our statement appeared to have no effect.
For brevity, I'll copy+paste an isolated test case I wrote to examine this behaviour:
main.pl
#!/usr/bin/perl
use warnings;
use strict;
use File::Basename;
# The variable to be read by the module.
our $verbose = 1;
# Load Output.pm from directory
use lib dirname "$0";
use Output;
write_message "Hello, world\n";
Output.pm
package Output;
use warnings;
use strict;
use parent "Exporter";
our #EXPORT = qw(write_message);
# Should be imported?
our $verbose;
sub write_message {
print $_[0] unless !$verbose;
}
1;
Expected result: "Hello, world"
Actual result: Dead silence
It's quite possible that what I'm trying to achieve isn't even possible in Perl, as this isn't the intended use of modules (and heck, I understand why that'd be the case).
I'm still quite new to Perl and there are some things I'm struggling to wrap my head around. I've seen people recommend using the our declarator to expose a variable across packages, but I can't understand why this isn't working.
PS: If anybody knows a better approach to splitting an app's program-specific logic between modules, I'd appreciate some pointers too. :) But first and foremost, I'd prefer to learn why our-ing a variable isn't working.
An our statement just creates a package variable (whereas my creates a lexical variable). It has nothing to do with exporting
The best option is probably to declare the variable in the Output package and access it as $Output::verbose elsewhere. Like this
main.pl
#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;
use lib dirname $0;
use Output;
$Output::verbose = 1;
write_message "Hello, world\n";
Output.pm
package Output;
use strict;
use warnings;
use Exporter 5.57 'import';
our #EXPORT = qw/ write_message /;
our $verbose;
sub write_message {
print $_[0] if $verbose;
}
1;
Note that I have also removed the incorrect quotes from around $0, and ever since version 5.57 of Exporter it has been possible (and preferable) to import it's import subroutine instead of subclassing it
our declares a package variable in the current package. The one in main.pl refers to $main::verbose; the one in Output.pm refers to $Output::verbose.
You can use the full name $main::verbose to access the variable from anywhere, but you can't really "export" it because exporting refers to making symbols accessible to users of your module. You're trying to do the opposite.