The innocent looking $# operator that we often use for determining the maximum index of an array in for loop can be sometimes dangerous.
I spent a sizable amount of time wondering why my for loop is becoming an infinite loop without realizing that writing something like this actually changes the max index value or $# value of an array
Say you have 2 dimensional array @sorted and you want to print the component. The easiest way would be:
for(my $i=0; $i <= $#sorted; $i++){
for(my $j=0; $j <= @{$sorted[$i]}; $j++){
print "$sorted[$i][$j]\t";
}
print "$#sorted\n";
}
The output will be a neat:
3349 4097 gene-PR001_g8806 9 ----> The last column indicates the max index
6662 6832 gene-PR001_g8807 9
11316 11696 gene-PR001_g8808 9
13158 13334 gene-PR001_g8809 9
18688 19095 gene-PR001_g8810 9
25175 25342 gene-PR001_g8811 9
26554 26883 gene-PR001_g8812 9
28100 29059 gene-PR001_g8813 9
29128 30235 gene-PR001_g8814 9
30266 30786 gene-PR001_g8815 9
Here one can notice the value of the last column is that of the max index of the array that remains unchanged and hence the lop terminates.
However, something as innocent as a c style this involving accessing the $i+1 element of the array actually changes the array maximum index!! This came as a surprise to me where I hit the infinite loop leading to out of memory and locked file alert.
Check this out::
for(my $i=0; $i <= $#sorted; $i++){
for(my $j=0; $j <= @{$sorted[$i]}; $j++){
print "$sorted[$i+1][$j]\t";---> Accessing the $i+1 value rather than $i value
}
print "$#sorted\n";
}
3349 4097 gene-PR001_g8806 9
6662 6832 gene-PR001_g8807 9
11316 11696 gene-PR001_g8808 9
13158 13334 gene-PR001_g8809 9
18688 19095 gene-PR001_g8810 9
25175 25342 gene-PR001_g8811 9
26554 26883 gene-PR001_g8812 9
28100 29059 gene-PR001_g8813 9
29128 30235 gene-PR001_g8814 9
30266 30786 gene-PR001_g8815 9
10
11
... --> Increases infinitely!
A potentially dangerous infinite loop where you are least suspicious!!!
A neat solution for this problem will be:
my $index = $#sorted;--> notice this statement
for(my $i=0; $i <= $index; $i++){
for(my $j=0; $j <= @{$sorted[$i]}; $j++){
print "$sorted[$i+1][$j]\t";
}
print "$#sorted\n";
}
6662 6832 gene-PR001_g8807 9
11316 11696 gene-PR001_g8808 9
13158 13334 gene-PR001_g8809 9
18688 19095 gene-PR001_g8810 9
25175 25342 gene-PR001_g8811 9
26554 26883 gene-PR001_g8812 9
28100 29059 gene-PR001_g8813 9
29128 30235 gene-PR001_g8814 9
30266 30786 gene-PR001_g8815 9
No comments:
Post a Comment