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.
Related
I'm creating my own module, lets call it X::Y. Of course, the module will be in the file X/Y.pm.
Lets say Y needs to call an external program, prog. Ideally I'd just like to put prog in X, so I can run X/prog. I'd like to not have hardcode X/progs full path, and for the module to work regardless of the current working directory set.
How can I find the full path of a module from inside a module? Or is there a better way to do this?
The full path to the source file currently being executed is supplied by Perl's __FILE__ special literal.
However I would prefer to see the external program installed where it would normally be, and the path there either coded as a constant in the Perl code or included in the PATH environment variable.
Borodin answered the question but some related information:
FindBin - finds the directory that the script was run from (use within the script itself or within a package loaded by it)
Neil Bower's CPAN modules for getting a module's path - detailed review of modules for finding another module's path.
Once a module is loaded, it's path is in the global %INC variable. To look it up, you need to do a simple conversion:
change :: in the package name to /
append .pm
So to find the location of the module X::Y, you would look in $INC{"X/Y.pm"}.
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';
I've started a module-starter (with --builder=Module::Build). I want to use SQL::Library to collect my SQL into an .ini file... but in order to find the file during run time, I need to know its exact path. How do I get the path of the "data directory" of a module at run time?
Until now, I've been using FindBin (like "$FindBin::Bin/../../path/to/module/datafiles/foo.ini", but I found this is not very robust (For example, it seems to break when there are two programs with the same name in two different dirs in PATH).
This is what File::ShareDir is for. Since you're using Module::Build, you'll need to set the share_dir parameter (and require Module::Build 0.36) in order to have your data files installed along with your module. Then, in your code, you'll use File::ShareDir to calculate the path of foo.ini (e.g. dist_file('My-Dist', 'foo.ini'))
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 '.';
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?