Why does Perl say that I use it only once? Why is this even a problem?

I have a code that I managed to narrow down to the next example of the smallest code.

First I have a plugh.pm module that is responsible for reading in the 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 that uses this module as follows, simply by calling a function to configure the configuration items, and then using one of these items in the routine:

 #!/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: the first line is a standard error, and the rest is standard.

 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 he complains about is the creation of the subprocess ls -1 . My question is simple: so what? Yes, I use it only once, but why is this even a problem?

If I have never used it, it’s good, but I don’t understand why Perl warns me about using it only once.

I get a variable from an associative array and then use it to get a list of directories. Is there some weird Perl directive in which state variables should be used at least twice? Seven times? Forty-two? I am seriously at a standstill.

+4
source share
3 answers

There are some unusual things here.

First: if you have use strict active, you will get a warning if you use a variable without declaring it, or referring to it with the full name.

What you actually did was declare a local %cfg with my() in xyzzy.pl , and then refer to another , global package variable %main::cfg (implicitly declared using its full name).

To link to the same %cfg that you declared, you must declare it our() to make it package-global. You can then refer to it as $main::cfg{} in both places (or just $cfg{} from xyzzy.pl ), otherwise you can declare it our() in plugh.pm (so you can use the bare% cfg in both places).

It is strange that you have two references to this variable, so you should not receive a warning. I think what happened here is that the implied declarations in two separate files are considered separate variables.

xyzzy.pl:

 require plugh; our (%cfg); sub subOne () { my $list = `ls -1 $cfg{"abc"}`; ... } 

plugh.pm:

 our(%cfg); sub cfgRead () { $cfg{"abc"} = "/usr"; } 
+9
source

I think I answered your original question, so I’ll just pass on my advice. Never use globals if you can avoid this. You use routines as simple clusters of code, and do not pass them any arguments and that where your problems arise.

Module:

 sub cfgRead { my %cfg; $cfg{"abc"} = "/usr"; ... return \%cfg; } 

Main:

 sub subOne { my $cfg = shift; my $list = `ls -1 $cfg->{"abc"}`; .... } my $cfg = cfgRead(); subOne($cfg); 
+12
source

This is just a useful comment because it is rather unusual to store data into something, but never look into it again. Let's look at a more useful example:

 use warnings; $something = 1; $something = $something + 1; 

This, of course, works just fine, as you would expect. But consider the error:

 use warnings; $something = 1; $something = $somehting + 1; 

If you did not look carefully, you would not notice a spelling error and probably could not understand why the final value was incorrect (since $somehting would be effectively 0).

In this case, a warning:

 Name "main::somehting" used only once: possible typo at tmp.pl line 3. 

This is much more useful. This shows a possible typo.

( use strict; it would be even better here, of course)

+6
source

Source: https://habr.com/ru/post/1394321/


All Articles