How to create own modules in Perl - perl

Module
package ExampleModule;
use strict;
use base "Exporter";
our #export = qw/hello_world/;
sub hello_world
{
print "Hello,world";
}
1
Test:
perl -c examplemodule.pm
examplemodule.pm syntax OK
Script:
use ExampleModule;
hello_world();
exit;
but I'm getting error
Error:
Can't locate ExampleModule.pm in #INC (#INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at until.pl line 229.
BEGIN failed--compilation aborted at until.pl line 229.
What is the wrong in my Module please let me know
EDIT
package ExampleModule;
use strict;
use base "Exporter";
our #EXPORT = qw(hello_world);
sub hello_world {
print "Hello,world";
}
1;
saved with ExampleModule.pm
#!/usr/bin/perl -w
use strict;
use lib "/home/Admin/Desktop/Perl_Work_Space/ExampleModule.pm/";
use ExampleModule ;
hell_world();
exit;
saved with first.pl
getting error
[Admin#localhost Perl_Work_Space]$ perl first.pl
Undefined subroutine &main::hell_world called at first.pl line 5.

You're missing path to your module in #INC. To fix it you can tell perl where to look for modules,
use lib "lib/"; # relative or absolute path to ExampleModule.pm
use ExampleModule;
hello_world();
Also ExampleModule.pm should have package line at the top, and use but don't inherit Exporter module,
package ExampleModule;
use strict;
use Exporter "import";
our #EXPORT = qw/hello_world/;
sub hello_world {
print "Hello,world";
}
1;

In addition to the use lib ...; statement, the packagename and the filename have to have the same spelling including the capitalization. So rename the file to ExampleModule.pm.
Although I'm wondering why perl -c examplemodule.pm does not emit a warning.
And you have to use our #EXPORT = qw/hello_world/;

Related

Perl script doesn't see modules .pm [duplicate]

This question already has answers here:
Doesn't Perl include current directory in #INC by default?
(3 answers)
Closed 2 years ago.
I have a perl scripts (proj_perl.pl , and proj_perl_client.pl) , I also created module proj_library.pm. My .pm looks:
package proj_library;
use base 'Exporter';
our #EXPORT = qw(help);
sub help{#my code}
1;
In my .pl scripts I invoke sub help and it looks:
#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';
use feature 'say';
use IO::Socket;
use JSON;
use proj_library qw(help); #LOOK HERE!
Then I invoke help somewhere in the code.
The problem is when I wan to run my script: ./pro_perl.pl Terminal shows me sth like this:
Can't locate proj_library.pm in #INC (you may need to install the proj_library module) (#INC
contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.30.0 /usr/local/share/perl/5.30.0
/usr/lib/x86_64-linux-gnu/perl5/5.30 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.30
/usr/share/perl/5.30 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at
./proj_perl.pl line 8.
BEGIN failed--compilation aborted at ./proj_perl.pl line 8.
So I don;t know what is going on!
Add the following to tell Perl to search in the script's directory:
use FindBin qw( $RealBin );
use lib $RealBin;
Did you check that your pm is in your #INC? If you need to load a custom PM folder, check perldoc.perl.org/lib
use as:
use lib "."
or
use lib "my_libs/"

How can I use an external lib in a BEGIN block

I want to use an external library in the BEGIN block of a Perl script.
The first test which I did was to check whether my #INC is getting popullated if I push some values:
use strict;
use warnings;
BEGIN {
push #INC, "d:/external_pm/";
use Data::Dumper;
print Dumper #INC;
}
Which works as expected and shows:
$VAR1 = 'D:/perl/5163/site/lib';
$VAR2 = 'D:/perl/5163/lib';
$VAR3 = '.'; # I am not sure about this one?!
$VAR4 = 'd:/external_pm/';
Now I want to import a module right after the push:
use strict;
use warnings;
BEGIN {
push #INC, "d:/external_pm/";
use Data::Dumper;
print Dumper #INC;
use ExtScript;
}
The error which follows is showing me that #INC was not updated:
Can't locate ExtScript.pm in #INC (#INC contains: D:/perl/5163/site/lib
D:/perl/5163/lib .) at file.pl line 9.
BEGIN failed--compilation aborted at file.pl line 9.
Why the #INC it's not updating?
I can't import a module in the BEGIN block? Or is a missusage of Perl?
use statements are executed at compile time (specifically, during the BEGIN phase), whereas normal code is run later. Let's look at this simplified snippet:
BEGIN {
push #INC, "some/dir";
use Example;
}
If we spell out all phases explicitly, that would be equivalent to:
BEGIN {
push #INC, "some/dir";
BEGIN { require Example; Example->import() }
}
So the Example module will be imported before the push runs.
There are a number of ways to address this.
The simplest way is to put only the #INC manipulation into a BEGIN block, and import the module outside:
BEGIN { push #INC, "some/dir" }
use Example;
A better solution is to use the lib pragma to handle #INC:
use lib "some/dir";
use Example;
However, there is a major difference: use lib puts additional directories at the beginning of the module search path, so you may accidentally override other modules. push #INC only adds directories to the end, as a fallback if a module wasn't found in other locations.
use ExtScript; is executed before push #INC. Either
move use ExtScript; out of the BEGIN block
or change it to require/import
or use the -I command-line option or PERL5LIB env variable.

In Perl, can't locate packgeName.pm in #INC error

This is a module math.pm with 2 basic functions add and multiply:
package Math;
use strict;
use warnings;
use Exporter qw(import);
our #EXPORT_OK = qw(add multiply);
sub add {
my ($x, $y) = #_;
return $x + $y;
}
sub multiply {
my ($x, $y) = #_;
return $x * $y;
}
1;
This is script script.pl that call the add function:
#!/usr/bin/perl
use strict;
use warnings;
use Math qw(add);
print add(19, 23);
It gives an error:
can't locate math.pm in #INC <#INC contain: C:/perl/site/lib C:/perl/lib .> at C:\programs\script.pl line 5.
BEGIN failed--compilation aborted at C:\programs\script.pl line 5.
How to solve this problem?
use lib
Adding a use lib statement to the script will add the directory to #INC for that specific script. Regardless who and in what environment runs it.
You just have to make sure to have the use lib statement before trying to load the module:
use lib '/path/to/module';
use Math qw(add);
For more details to set #INC look at this:
How do I include a Perl module that's in a different directory
Add the following to script.pl before use Math ...;:
use FindBin qw( $RealBin );
use lib $RealBin;
If script.pl and math.pm aren't in the same directory, adjust accordingly.
Also, you might have problems if the file is named math.pm and you use use Math; and package Math;. It would be best to rename the file so the spelling is consistent.
ren math.pm Math.pm

Perl module in #INC path, but can't be located though present. Other modules are found

Perl module DBD::mysql was being found and now is not. I'm getting the error message.
Can't locate DBD/mysql.pm in #INC (#INC contains: /usr/local/lib64/perl5
/usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /mnt/Lab/Data/IonTorrent/plugins/WH_v2_05/scripts/create_blinded_reports.pl line 13.
BEGIN failed--compilation aborted at /mnt/Lab/Data/IonTorrent/plugins/WH_v2_05/scripts/create_blinded_reports.pl line 13.
I looked to see where the module was located.
$ perldoc -l DBD::mysql
/usr/lib64/perl5/DBD/mysql.pm
the path /usr/lib64/perl5 is there so why can't it find it.
Here is the code.
#!/usr/bin/perl -w
use strict;
use DBI;
use DBD::mysql; #<----- this is the line that error (I eliminated the header, this is actually line 13.)
use File::Slurp;
use Data::Dumper;
my ($server,$run)=#ARGV;
## variables
my $wh_report="/mnt/Lab/Data/IonTorrent/$server/$run/4_report/wh_report_".$run.".txt";
** Also I checked that I was on the correct server.
It also compiles fine.
perl -c create_blinded_reports.pl
create_blinded_reports.pl syntax OK
I dropped use DBD::mysql; from the code and it ran fine. Thanks!

Can't locate WWW/Mechanize.pm in #INC

I am trying to get this sample code that I found on a site to work:
#!/usr/bin/perl
use v5.10;
use WWW::Mechanize;
use WWW::Mechanize::TreeBuilder;
my $mech = WWW::Mechanize->new;
WWW::Mechanize::TreeBuilder->meta->apply($mech);
$mech->get( 'http://htmlparsing.com/' );
# Find all <h1> tags
my #list = $mech->find('h1');
# or this way
# Now just iterate and process
foreach (#list) {
say $_->as_text();
}
When I run it I get this message:
Can't locate WWW/Mechanize.pm in #INC (#INC contains: /Library/Perl/5.16/darwin-thread-multi-2level /Library/Perl/5.16 /Network/Library/Perl/5.16/darwin-thread-multi-2level /Network/Library/Perl/5.16 /Library/Perl/Updates/5.16.2 /System/Library/Perl/5.16/darwin-thread-multi-2level /System/Library/Perl/5.16 /System/Library/Perl/Extras/5.16/darwin-thread-multi-2level /System/Library/Perl/Extras/5.16 .) at test2.pl line 4.
BEGIN failed--compilation aborted at test2.pl line 4.
Does anyone have any ideas on what is happening?
WWW::Mechanize is a Perl module. You need to install it. The easiest way is to run cpanm:
cpanm WWW::Mechanize
Note that your code says use WWW::Mechanize::TreeBuilder, which means you need to install that library as well. As its name suggests, it depends on WWW::Mechanize, which will be automatically installed if you run
cpanm WWW::Mechanize::TreeBuilder