Search code examples
perlglobal-variablesrequireperlvar

Is it possible to trick Perl to use a variable %INC and still keep the global %INC untouched?


I have just found a script we are using which has a sub that says my %INC in it, where it stores some values about incentives, thus %INC. This never seemed to be a problem, or no-one ever noticed. For me it produced 20 screens of redefine warnings, because %INC, holding all the file names Perl has done, required or used, was pretty large, and now is ('stuff' => 123).

Do I really have to go and rename every single reference to this in the sub, or is there another way to make Perl forgive this ... ?


Here's a part of the output of:

print Dumper \%INC; # I added this line
my %INC;             
print Dumper \%INC; # I added this line
exit;               # I added this line

Output:

          [...]
          'SqlConnect.pm' => 'lib1/SqlConnect.pm',
          'Lib/RateRequest.pm' => 'Lib/RateRequest.pm'
        };
$VAR1 = {};
[Fri Jun 29 16:09:13 2012] live_batch_test.pl: Subroutine export_fail redefined at /usr/lib/perl5/5.14.2/Carp.pm line 43.
[Fri Jun 29 16:09:13 2012] live_batch_test.pl: Subroutine _cgc redefined at /usr/lib/perl5/5.14.2/Carp.pm line 45.
[Fri Jun 29 16:09:13 2012] live_batch_test.pl: Subroutine longmess redefined at /usr/lib/perl5/5.14.2/Carp.pm line 51.
[Fri Jun 29 16:09:13 2012] live_batch_test.pl: Subroutine shortmess redefined at /usr/lib/perl5/5.14.2/Carp.pm line 71.
[...] (Snipped like 20 screens of redefine warnings)

The warnings only show if I create an object of one of my classes (which happens to contain SOAP::WSDL so it has a lot of stuff in it). I'm not sure why those are redefine warnings. If %INC is empty, how can it know stuff is being redefined?


Update:

It seems you actually can create a lexical my %INC.

use strict; use warnings; use Data::Dumper;
print Dumper \%INC;
{
  my %INC = ('asdf' => 'asdf');
  print Dumper \%INC;
}
print Dumper \%INC;

Produces (snipped):

          'feature.pm' => 'C:/Perl/lib/feature.pm'
        };
$VAR1 = {
          'asdf' => 'asdf'
        };
$VAR1 = {
          'warnings/register.pm' => 'C:/Perl/lib/warnings/register.pm',

The problem in my case does not seem to be the my %INC, but rather the %INC = &sub_that_has_my_percent_INC_and_returns_it() in the script that I actually have to require. Now that, in turn, also has use vars qw(%INC). Replacing it... well, I'm not sure what that is going to break.


Solution

  • The global variable %INC (or %main::INC or %::INC) is a completely different variable from the lexically scoped %INC, created with my. You can safely use my %INC in your subroutine.