In a legacy project at work, we have lots of scripts that should in fact be modules. But they declare no package, use the .pl extension and call each other via require. Originally, the full paths were used in require, which constituted one of the obstacles to run the project locally. I replaced all the occurrences of
require '/path/to/some/script.pl';

with

use lib '/path/to/some'; require 'script.pl';

and I was able to run some of the scripts locally (I had to add some paths to @INC).

After several days, we noticed some of the scripts failed. I inspected the code and discovered that there was one newer OO module that was written "correctly": it lived in a .pm file and declared a package. It used lib and only required the script names.

Combining "right" and "wrong" led to "even worse": The OO module required several .pl files. All the subroutines they declared were therefore created in the namespace of the module. Later, when a calling script required the same .pl file, it already existed in %INC, so it was not read again. No import was called anywhere, so the subroutines did not appear in the main:: package.

Here are sample files so you can try it yourself:

module.pm

package module; use warnings; use strict; require 'required1.pl'; subroutine(); warn 'module INC: ', $INC{'required1.pl'}; __PACKAGE__

required1.pl

#!/usr/bin/perl use warnings; use strict; warn "Loading 1"; sub subroutine { my $file = (caller)[1]; $file =~ s=.*/==; warn 'subroutine defined in ', $file; } subroutine(); 1;

script.pl

#!/usr/bin/perl use warnings; use strict; use FindBin; use lib $FindBin::Bin; require 'required1.pl'; use module; warn 'script INC ', $INC{'required1.pl'}; subroutine();

Update:

The Conclusion

We now have 2 options:

  1. Revert to the original full-path style require with no possibility to run the project locally.
  2. Refactor everything to proper modules. 100,000+ lines.

Update2:

I just had an idea: there is a third option. In the OO module, store %INC at the beginning, do all you need, then set %INC back to what it was.

my %_INC = %INC; # ... %INC = %_INC;
لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

In reply to Wrong + Right = Even Worse by choroba

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.