Home > Back-end >  If I declare a package with multiple levels of embedding, does the module named as the leaf node nee
If I declare a package with multiple levels of embedding, does the module named as the leaf node nee

Time:03-24

I am dealing with some legacy Perl code, which I want to change as little as possible. The main script, call it "myscript.pl" has a structure like this

use MyCompany::ABDoc::HTMLFile;
use MyCompany::ABDoc::JavaScriptFile 2014.004_015;

print "Howdy"
...

The HTMLFile.pm module looks like this

package MyCompany::AMDoc::HTMLFile;

...

I am troubleshooting my_script.pl, and wish to run it from the command line. (It normally is triggered by a Jenkins job). When I try

perl -d ./my_script.pl 

I get a message about HTMLFile.pm not being found. This is because hte HTMLFile.pm actually exists at the same level as my_script.pl in the filesystem.

If this was my own script, and I had the freedom to move things around, I would create directory structure

MyCompany/AMDoc/HtmlFile.pm

and I know the script would work. But I am reluctant to do this, because somehow, this all runs fine when triggered by the Jenkins job.

So is it possible to run this code, from the command line, without moving anything? I just want to do some troubleshooting. I haven't found discussion in the Perl documentation about what kinds of command line flags, such as "-I", might help me out here.

CodePudding user response:

I would create directory structure MyCompany/AMDoc/HtmlFile.pm and I know the script would work.

No, moving the file to MyCompany/AMDoc/HTMLFile.pm relative to the script would not work unless the script already takes steps to add its directory to @INC.[1]

For example, adding the following in the script would achieve that:

use FindBin qw( $RealBin );
use lib $RealBin;

This can also be done from without

perl -I "$dir" "$dir"/my_script.pl    # General case

perl -I . ./my_script.pl              # Specific case

So is it possible to run this code, from the command line, without moving anything?

No, not without modifying the script.[2]

According to what you gave us, it has to be accessible as MyCompany/AMDoc/HTMLFile.pm relative to a directory in @INC.


  1. It would happen to work if the script's current work directory happened to match the directory in which the script is found in old version of Perl. But that's just a fluke. These frequently don't match.

  2. Well, you could use something of the form

    perl -e'
       use FindBin qw( $RealBin );
       my $s = shift;
       push @INC, sub {
          my ( undef, $path ) = @_;
          my ( $qfn ) = $path =~ m{^MyCompany/AMDoc/(.*)}s
             or return;
          open( my $fh, '<', $qfn )
             or return;
          return $fh;         
       };
       do( $s ) or die( $@ // $! );
    ' ./my_script.pl
    

    Even then, that expects the script to end in a true value.

CodePudding user response:

My initial assumption was wrong. My code was actually running on a Kubernetes pod, and that pod was configured with the correct directory structure for the module. In addition, PERL5LIB is set in the pod.

PERL5LIB=/perl5lib/perl-modules:/perl5lib/perl-modules/cpan/lib64/perl5:/perl5lib/perl-modules/cpan/share/perl5

and sure enough, that very first path has the path to my module.

  • Related