Reputation: 362
I have an array of numeric values that's sorted. I also have a minimum and maximum value and want to remove any values from the array that are smaller than the minimum or bigger than the maximum value. I am getting an endless loop when my minimum value is smaller than the value of the first array element. Here's a minimal example of the code in question:
#!/usr/bin/perl
use strict;
use warnings;
my @array = ( 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 );
my $min_wert = 1;
my $max_wert = 13;
while ( $array[0] < $min_wert ) {
shift @array;
}
while ( $array[-1] > $max_wert ) {
pop @array;
}
print join( ' ', @array );
print "\n";
The problem is, this version works flawlessly, outputting
5 6 7 8 9 10 11 12 13
The first while is not entered in this case.
Dropping the same test case into my production code, I'm getting the following error message on the line with the shift-statement:
Use of uninitialized value in numeric lt (<) at line 1130.
I then introduced a counter to try to figure out why the while-loop is even entered, and that completely removes the problem instead of giving me the opportunity for further diagnostics.
@werte_liste = sort {$a <=> $b} @werte_liste;
print join( ' ', @werte_liste );
print "\n";
print "Start: $start_index - Stop: $stop_index\n"
while ( $werte_liste[0] < $start_index ) {
print "In while-loop- why?\n";
shift @werte_liste;
}
while ( $werte_liste[-1] > $stop_index ) {
pop @werte_liste;
}
why do I enter that first while loop in this case? And second, is there a better solution to my specific problem (I'm not talking lots of values here, so readability of code is more important than efficiency).
Upvotes: 0
Views: 71
Reputation: 210
I don't know why it works with your testcase but doesn't in your production code, but here's my guess:
Your array becomes empty. $array[0] < $min_wert
is true if $array[0]
is undef
(which happens if the array is empty), and $min_wert > 0
.
undef
is basically treated as a 0
in numerical comparisons (it emits a warning).
You can check that the array still has elements with this:
while ( @array and $array[0] < $min_wert ) {
The other while
loop probably has the same problem.
Upvotes: 3
Reputation: 118605
What happens when @werte_liste
is empty?
For one, $werte_liste[0]
will be undefined, and the expression $werte_liste[0] < $start_index
will generate the Use of uninitialized value in numerlic lt ...
warnings.
For another, $werte_liste[0]
will evaluate to 0 for the <
comparison. If $start_index
is positive, then $werte_liste[0] < $start_index
is true.
Finally, shift @werte_liste
will have no effect on @werte_liste
, @werte_liste
will remain empty, and your while ...
expression will repeat indefinitely.
Upvotes: 1