Reputation: 840
Small debug question I can't solve for some reason. Consider the following code:
use warnings;
my $flag = 0;
foreach my $i (0..scalar(@ARGV)) {
$data{$OPTION} .= $ARGV[$i]." " if($flag);
$flag = 1 if($ARGV[$i] =~ /$OPTION/);
undef $ARGV[$i] if($flag);
}
I get the following two warnings:
Use of uninitialized value within @ARGV in concatenation (.) or string at line 4
Use of uninitialized value in pattern match (m//) at line 5
I get the reason is that I undefine some value of @ARGV
and then it tries to check it.
The way I do it like this is because I would like to 'cut' some of the data of @ARGV
before using GetOpt
module (which uses this array).
How to solve it?
Upvotes: 0
Views: 63
Reputation: 69244
Let's expand on those comments a bit.
Imagine @ARGV
contains four elements. They will have the indexes 0, 1, 2 and 3 (as arrays in Perl are zero-based).
And your loop looks like this:
foreach my $i (0..scalar(@ARGV)) {
You want to visit each element in @ARGV
, so you use the range operator (..
) to generate a list of all those indexes. But scalar @ARGV
returns the number of elements in @ARGV
and that's 4. So your range is 0 .. 4. And there's no value at $ARGV[4]
- so you get an "undefined value" warning (as you're trying to read past the end of an array).
A better way to do this is to use $#ARGV
instead of scalar @ARGV
. For every array variable in Perl (say @foo
) you also get a variable (called $#foo
) which contains the last index number in the array. In our case, that's 3 and your range (0 .. $#ARGV
) now contains the integers 0 .. 3 and you no longer try to read past the end of the array and you don't get the "undefined value" warnings.
There's one other improvement I would suggest. Inside your loop, you only ever use $i
to access an element from @ARGV
. It's only used in expressions like $ARGV[$i]
. In this case, it's probably better to skip the middle man and to iterate across the elements in the array, not the indexes.
I mean you can write your code like this:
foreach my $arg (@ARGV) {
$data{$OPTION} .= $arg . " " if($flag);
$flag = 1 if($arg =~ /$OPTION/);
undef $arg if($flag);
}
I think that's a little easier to follow.
Upvotes: 3