I have some code that I’ve managed to narrow down to the following smallest-code sample.
First I have a module plugh.pm which is responsible for reading in a configuration file. The meat of this can basically be replaced with the following, which sets up one configuration item:
use strict;
use warnings;
sub cfgRead () { $main::cfg{"abc"} = "/usr"; }
1;
Then I have a main program which uses that module as follows, simply calling the function to set up configuration items, then using one of those items in a subroutine:
#!/usr/bin/env perl
use strict;
use warnings;
use 5.005;
require File::Basename;
import File::Basename "dirname";
push (@INC, dirname ($0));
require plugh;
my (%cfg);
sub subOne () {
my $list = `ls -1 $main::cfg{"abc"}`;
my @list = split (/\s+/, $list);
my $fspec;
foreach $fspec (@list) {
print $fspec . "\n";
}
}
sub mainLine () {
cfgRead();
subOne();
}
mainLine();
Now, when I run this, I get the following output with the first line being standard error and the rest being standard output:
Name "main::cfg" used only once: possible typo at /home/xyzzy/bin/xyzzy line 15.
bin
games
include
lib
lib64
local
sbin
share
src
The line it’s complaining about is the ls -1 subprocess creation. My question is simply: so what? Yes, I only use it once but why is that even an issue?
If I was never using it, then fine, but I can’t see why Perl is warning me about only using it once.
I get the variable from the associative array and then use it to get a directory listing. Is there some sort of bizarre Perl guideline that states variables have to be used at least twice? Seven times? Forty-two? I’m seriously stumped.
There are a few odd things here.
First: when you have
use strictactive, you will get a warning if you use a variable without declaring it, or referencing it by fully qualified name.What you have actually done is to declare a local
%cfgwithmy()inxyzzy.pl, and then to reference a different, package-global variable%main::cfg(implicitly declared by using its fully qualified name).To make the reference link to the same
%cfgthat you declared, you should declare itour()to make it package-global. Then you can either reference it as$main::cfg{}in both places (or just$cfg{}fromxyzzy.pl), or else you can declare itour()inplugh.pmas well (so that you can use the bare %cfg in both places).The odd thing is that you do have two references to that variable, so you shouldn’t get the warning. I think what has happened here is that the implicit declarations in two separate files are assumed to be separate variables.
xyzzy.pl:
plugh.pm: