Perl package file Can't locate [duplicate] - perl

This question already has answers here:
Doesn't Perl include current directory in #INC by default?
(3 answers)
Closed 4 years ago.
I have integrate sample function in perl. Everything working fine but i am not able to connect Perl module package file(.pm)
Please review below code
sample.pl
#!/usr/bin/perl
use strict;
use warnings;
use Sample;
print Sample->test_function();
Sample.pm
package Sample;
sub test_function
{
return 'Welcome';
}
Once after run the sample.pl file. It's return the error "Can't locate Sample.pm " but the package file availale in same folder.

The reason of the issue is installed perl module location could not found . add the below line your sample.pl file
use strict;
use warnings;
use Cwd qw( abs_path );
use File::Basename qw( dirname );
use lib dirname(abs_path($0));
use Sample;
print Sample->test_function();

First of all, your Sample.pm file must finish returning a true value. The common way to do that is appending 1; and the end of that file.
package Sample;
use strict;
use warnings;
sub test_function {
return 'Welcome';
}
1;
After Perl 5.26, current directory was removed from #INC. There are several ways to deal with this. For example, you can use the -I option when running the script:
perl -I. sample.pl
For a more deeper lecture on how to deal with #INC, please read this SO post.

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/"

Undefined subroutine &main::key_enc

I have a Perl module named McuEnc.pm which is located at /home/eric/temp directory:
package McuEnc;
use 5.010;
use strict;
use warnings;
use Exporter qw(import);
our #EXPORT_OK = qw(key_enc data_enc data_dec);
sub key_enc { some code }
sub data_enc { some code }
sub data_dec { some code }
1;
I have a Perl script named test.pl which is also located at /home/eric/temp directory:
use 5.010;
use strict;
use warnings;
use McuEnc qw(key_enc data_enc data_dec);
key_enc("1111");
...
I have changed working directory to /home/eric/temp. Now if I run test.pl script, it runs correctly. But if I create a new directory /home/eric/temp/My and move the McuEnc.pm file into it and then modify the test.pl script as follwoing:
use 5.010;
use strict;
use warnings;
use My::McuEnc qw(key_enc data_enc data_dec);
key_enc("1111");
...
then I'm getting the following error when I run test.pl again:
Undefined subroutine &main::key_enc called at ./test line 6.
However, I can still call the subroutine correctly with:
McuEnc::key_enc("1111");
So why I'm getting the error message? what is wrong?
This was answered by Sobrique in the comments, but it was never posted as an official answer:
"The use statement doesn't match the package statement. Try package My::McuEnc instead"

How to have conditional libraries with Perl? [duplicate]

This question already has answers here:
Perl - Include package from relative path, which includes another package from a relative path?
(4 answers)
Closed 8 years ago.
I have homemade #Perl libraries that I'm moving from machine to machine, and the paths are not the same from place to place. Specifically, on the old machines, they existed in /home/foo/lib/, while they're moving to /group/bar/apps/lib on the new machines, and I now want to have them in something like /home/me/dev/Tools/lib.
What we did was have multiple use lib lines. /home/foo isn't available on the new machine, and /group/bar isn't a directory on the old machine, so when it sees this --
use lib '/home/foo/lib/' ;
use lib '/group/bar/apps/lib' ;
use Tools::Foo ;
-- everything is fine.
The problem is, they link to each other, and I'd rather not have something in /home/me/dev/Tools/lib load a program from /group/bar/apps/lib, and when I move this stuff to production, I don't want to have anything pointing back to ~/me/dev. Preferrably, I would want to not have to modify the code when I move it into production, so that, when everything is deployed, diff /group/bar/apps/lib/Tools/Foo.pm /home/me/dev/Tools/lib/Tools/Foo.pm would be empty.
So, how do I set things for multiple conditional library locations?
Options:
Properly install the modules.
Place your modules relative to the script
use FindBin qw( $RealBin );
use lib "$RealBin/../lib"; # Or whatever.
Use environment variable PERL5LIB rather than use lib.
The statements could be placed in sitecustomize.pl (if support for sitecustomize.pl was enabled when perl was built).
Using the following pragma
package lib_first_of;
use lib ();
use strict;
use warnings;
use Carp;
sub import {
foreach my $path (#_) {
if (-d $path) {
lib->import($path);
return 1;
}
}
croak "$0: no suitable library path found";
}
1;
lets your main program have the form
#! /usr/bin/env perl
use strict;
use warnings;
use lib_first_of (
"/home/foo/lib",
"/group/bar/apps/lib",
);
use MyModule;
print "done.\n";
If neither path is present, the program fails with errors resembling
my-program: no suitable library path found at my-program line 7
BEGIN failed--compilation aborted at my-program line 9.

Why doesn't my Perl script use my module?

module.pm
package module;
use 5.012;
use warnings;
sub Parse
{
return 1;
}
1;
script.pl
#!/usr/bin/perl -w
use 5.012;
use warnings;
use lib 'C:/';
use module;
print Parse("value");
Stdout
Undefined subroutine &main::Parse
You need either to write:
print module::Parse("value");
or to change the module package to export the name Parse.
See http://perldoc.perl.org/perlmod.html#Perl-Modules for guidance in exporting symbols from your module.
(By the way, you should really name your module Module rather than module. Lowercase module-names are used for Perl built-in features like use warnings and use strict.)
Several things:
First, use Local as your module prefix. That way, if you just happen to have a module with the same name in your Perl installation, it will use yours. Call it "Local::Module". Then, create a Local directory, and name your module Module.pm.
The other thing you have to understand is that you define your module in another namespace. By default, everything is in the main namespace until you use the package statement. That creates another namespace that your package uses. This way, if your package has a function foo, and you've defined a function foo in your main program, they won't collide.
Thus, you have two choices: One (the preferred now) is to simply call your subroutine with the full package name prepended to it. The second is to export your subroutine names to your main program. This can cause problems with duplicate names, but you don't have to keep typing in the package name every time you call your subroutine.
Without Exporting the name
Local/Module.pm
# /usr/bin/env perl
# Local/Module.pm
package Local::Module;
use strict;
use warnings;
sub Parse {
my $value = shift; #Might as well get it.
print "I got a value of $value\n";
return $value;
}
1; #Need this or the module won't load
program.pl
# /usr/bin/env perl
# program.pl
use strict;
use warnings;
use Local::Module;
Local::Module::Parse("Foo");
With export:
Local/Module.pm
# /usr/bin/env perl
# Local/Module.pm
package Local::Module;
use strict;
use warnings;
use Exporter qw(import);
our #EXPORT_OK(Parse); #Allows you to export this name into your main program
sub Parse {
my $value = shift; #Might as well get it.
print "I got a value of $value\n";
return $value;
}
1; #Need this or the module won't load
program.pl
# /usr/bin/env perl
# program.pl
use strict;
use warnings;
use Local::Module qw(Parse);
Parse("Foo");

Perl problem 'require' the same file

I have a shared module in perl. The main program needs two files, first, a shared file (let's call it 'X'), and, second, a 'package' file. File 'X' is also included in the 'package' file using 'require'. When I compile this program it gives me the following error:
Undefined subroutine &main::trim called at testing.pl line 8.
My understanding is that perl couldn't find the trim() module. If I don't include the package file, then this will run without any problem.
Can anyone shed light on this problem?
These are my codes:
Main program: testing.pl
#!/usr/bin/perl -w
use strict;
use postgres;
require "shared.pl";
trim("als");
Package File: postgres.pm
#!/usr/bin/perl
package postgres;
use strict;
use DBI;
require "shared.pl";
1;
shared file: shared.pl
#!/usr/bin/perl
# =============
# shared module
# =============
use strict;
sub trim($)
{
}
1;
If the module doesn't use package, you want do instead of require. See What is the difference between library files and modules?.
do "shared.pl" or die $#;
You really should create a proper module, one with a package statement.
package Shared;
use strict;
use warnings;
our #EXPORT = qw( trim );
use Exporter qw( import );
sub trim { ... }
1;
Name the file Shared.pm and load it using use Shared;.
By default, require will only load a file one time. In this case, that one time is from the file postgres.pm, in the postgres package. So the trim subroutine gets defined in the postgres namespace as &postgres::trim.
One workaround would be to use the fully qualified subroutine name in the testing.pl file:
postgres::trim("als"); # not trim("als")
Another workaround is to hack the %INC table (the variable that keeps track of what modules/files have already been use'd and require'd) so you can reload shared.pl into the main package:
use postgres;
delete $INC{"shared.pl"};
require "shared.pl";
A third workaround would be to export the trim function from the postgres package to the main package. The docs for the Exporter module are a good introduction to why and how this is done.
# in postgres.pm
*main::trim = *trim;
# or in testing.pl
*trim = *postgres::trim;
trim("als");