kotoko has asked for the wisdom of the Perl Monks concerning the following question:

Hi!

I can't understand why the following code outputs as if the array had only one element.

Does it really have just one element? If yes, why? (since I call the sorter sub 2 times)

If I take out the my's it outputs as having 3 elements. Really confused. Here is the code:

#!/usr/bin/perl use strict; my $lineA = "CTACACTTCCATGACCACACATTAATAATTGTGTTCCTAATTAGCTCATTAGTACTC +TAC"; my $lineB = "CTACACTTTCACGATCATACACTAATAATCGTTTTTCTAATTAGCTCTTTAGTTCTC +TAC"; sub altrIter{return (($_[0] % 10)) }; sub altrInc {return ($_[0]+1) }; &sorter ($lineA, \&altrIter, \&altrInc); &sorter ($lineB, \&altrIter, \&altrInc); my @allSeq; my $index=0; sub sorter { my $i = &{$_[1]}($index); $allSeq[$i]= ($allSeq[$i].$_[0]); $index = &{$_[2]}($index); print "in: ".$_[0]."\n"; } for (my $i = 0; $i <= $index; $i++){ print "seq -->".$allSeq[$i]."\n"; }
Thanks for any help.

Replies are listed 'Best First'.
Re: confusing number of elements in an array
by chromatic (Archbishop) on Apr 05, 2007 at 17:17 UTC

    $index gets reset to zero before the final loop. Notice that your calls to sorter() occur in the code before the assignment to $index.

    Moving your code around will help. A better idea is to use native iteration, though, as you don't use the array index:

    for my $seq (@$allSeq) { print "seq -->$seq\n"; }

    (As a style note, I spent a lot of time deciphering your code; using variable names in your subroutines for parameters would really help. Also, I find it much easier to call subs by reference with the $subref->( @args ) syntax; it's much less visually cluttered.)

    Update: ikegami pointed out a typo.

Re: confusing number of elements in an array
by ambrus (Abbot) on Apr 05, 2007 at 17:14 UTC

    I think there are two problems with your code. The more serious one is that you initialize the $index variable to zero after you increment it by calling sorter. Thus, $index will be zero by the time you print the array. The lesser problem is an off-by-one error in the for loop: the halting condition should be $i < $index, as $index points after the last element of the array.

Re: confusing number of elements in an array
by kyle (Abbot) on Apr 05, 2007 at 17:21 UTC

    Your output loop uses $index, and you set $index=0 after your calls to sorter. If you want the actual contents of your array without $index, you can do that this way:

    foreach my $seq ( @allSeq ) { print "seq -->$seq\n"; }

    I suggest also that you use warnings and that you name the parameters to your subs:

    sub sorter { my ( $line, $iter_sub, $inc_sub ) = @_; my $i = $iter_sub->($index); $allSeq[$i] .= $line; $index = $inc_sub->($index); print "in: $line\n"; }