Can I call a .pl file from a module in perl? - perl

I have created a Perl module from a .pl file and I am testing it at the moment. It works until the point where it needs to use another .pl file (to pull out some sql statements). I am calling the file using require 'file.pl';. This is a temporary solution as the .pl file will be replaced in the future by a better database solution, but for now I need to test my module code. It doesn't like trying to find the file, though, even though I have put the path name in #INC using use lib '/path/to/file'.
Is there any temporary solution I can use to solve this problem? I don't know when the .pl file will be replaced, so I can't rely on waiting for that. Should I just move the sql statements into the .pm file even though I will have to remove them later, or do I have to search out the folder that the module is in the put a copy of the .pl file in it?

You can require the full pathname:
require '/path/to/file.pl';

Related

Perl: "Install" a custom module from a local .pm file into the Perl execution environment?

Perl newbie here with very little time and support to learn Perl but all the expectations from management to use it like a Perl Pro :)
I am using Perl (v5.30.2 by Larry Wall) under Cygwin (windows 10)
My developer issued a new script, that now uses a Perl module I didn't have.
They then sent me the .pm file (which they authored themselves and it is not on any online Perl repo).
I was unable to use CPAN to install that file into my Perl execution environment.
Where should the .pm file be saved at? (please specify the exact folder)
How to tell CPAN to install this file for usage? Ideally, a one-time affair, as I don't want to forget installing this file, if I have to do that every time I need to run the Perl script...
Just in case there may be any security concern from the dear answer-ers: There isn't any security concern here, this is all under an environment that has no connection to the internet.
A Perl module is just a file (or collection of files). You don't have to put them anywhere special, but you need to tell Perl where to find them.
When you call use or require with a bareword, Perl translates that module name, like Some::Module, into Some/Module.pm (or whatever is appropriate for your system. Anyone still using VMS?).
Once it has the filename form of the module, it looks for that subpath in the directories in #INC. It tries the first directory. If it doesn't find it it moves on to the next, and so on down the line. These directories are decided when someone configures and installs Perl. And, before v5.26, it included the current working directory (see v5.26 removes dot from #INC and Doesn't Perl include current directory in #INC by default?
)
But, you can tell Perl where else to look. perlfaq8 has How do I add a directory to my include path (#INC) at runtime?. ikegami also showed FindBin in the comments (How do I add the directory my program lives in to the module/library search path?).
Beyond that, you can tell require to load a path, although you then need to ensure that the program can find that path even if someone runs it from another directory
require './this_file/over/here';
require '/usr/local/lib/this_file/over/here';

Perl file extension

We have few files which don't have the standard perl extension like cgi etc.
Couple of them end with *.cfm and have perl code in them.
Now i am not sure why the developer decided to use a coldfusion extension and decide to use perl in it, but we are at a point now where we cannot alter the filename and we need to make some configuration changes such that perl is able to render *.cfm files too.
Is there a way we can modify the perl configuration to accept *.cfm files and render them as perl scripts?
I'll go out on a limb and guess that your actually asking about running ".cfm" files as CGI scripts, through Apache. In that case, you would use a "handler" to tell Apache to treat all *.cfm files as Perl scripts. If I've guessed what's going on, then add this to your Apache 2.2 configuration:
AddHandler cgi-script .cfm
Also, make sure the Perl scripts have the right "shebang" line on the first line, usually:
#!/usr/bin/perl
If you want some *.cfm files to be still be treated as Cold Fusion, then you'll need a different solution.

import/require/use for perl modules

I have 2 files perl files which have dependency on one another.
The 1st file, A is a .pl file which multiple package/modules declared inside.
The 2nd file, B will try to access one of the many packages declared in file A. How can that be done?
You may be familiar with how Java or a similar language finds an import com.example.AppName namespace by looking for the com/example/AppName.java file in the classpath. When you ask Perl for use HTML::Template, it likewise looks for HTML/Template.pm in the directories listed in #INC.
The difference is that a Perl file can have multiple packages. When you say use HTML::Template, you'll be pulling in all packages listed in HTML/Template.pm (use automatically translates the :: into the right directory separator for your system, and adds the .pm). If there happens to be a HTML::Template::Extension package in that file, then you can use that package without having to explicitly use it. It's already loaded the complete file, and that's good enough.
If you know the exact file name relative where you'll be running the script, the easiest way to grab it is:
require 'path/to/file.pl';
You need to declare a module in each pl file that is using a function of the module.

How do I best use a library whose directory may change occasionally?

I am writing Perl scripts and when I have too many functions, I usually move them all into a library (also good for code reuse). So I usually create a package (e.g. my_lib.pm) and add use lib 'path/to/lib'; use my_lib; to my script.
I wonder if it's possible to skip the use lib 'path/to/lib';, which sometimes gives me trouble since I reorganize my directory hierarchy, and make Perl look for packages in the same dir where the script is running from.
Thank you.
First, i suggest you - "Never mess up with Core Perl and its libraries - never put your lib in among there".
If you want your script look into current dir, then use like:
require "mylibrary/functions.pm";
where mylibrary is a dir that exists the same path as your caller script.
I would put my .pm file into one directory so you can use if from Perl scrips irrespective of their location.
Then create an envrironment variable PERL5LIB with the name of that directory.
You need
use lib '.';

How can I force Perl to run the module from the test directory only?

I have perl module file and test script pl which I use to run some function, and after browsing through the use lib and this previous question here...
I still don't know how to do this.
Basically I have a production directory which contains the module file, and I have a test directory file which contains the same module and the test script file. each time I try to run the script file, it will automatically calls the module in the directory. by printing out the #INC, it seems that the production directory is hosted in there. thus I try to remove it by using
no lib qw(prod_dir);
and while printing out the #INC shows that the directory is no longer there, somehow the script is still calling that other module...
I know this probably sounds really dumb, but hope someone can help me see the light here :)
thanks.
After you have required or used the module, check %INC to see where it came from.
For example:
use Data::Dumper;
print $INC{'Data/Dumper.pm'}."\n";
Note that "::" becomes "/" and you append ".pm". That might give you a clue.
Remember that the current directory (".") is usually an entry in #INC. But the first step is finding out what directory the module was loaded from.
Another thing to remember is that the directories in #INC are searched in order. use lib prepends to that list (making it the first-searched directory), so you may just need to add the appropriate directory.
Can you say more about what you are trying to do and how you are trying to do it? Is this stuff in a standard Perl distribution structure? If you aren't using the standard distribution structure, can you show us a directory listing so we know where things are? Can you also include the code you use to try to load the module? Just update your original question when you pull together the details.
Typically, I run tests through the build runner, which automatically sets up the right #INC.
If I want to run one test in my distribution, I use the blib module to find the build library which has the development versions of my modules:
% perl -Mblib t/test.t
Some people do the same thing with prove.
If you aren't using the basic distribution set-up, consider using it. The tools and best techniques rely on it.
If you just have your module and test file in the same directory, have you tried adding the current directory to #INC with PERL5LIB?