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

@partners contains one or more elements, depening on the input to the script. I have tested and know that the correct information is getting into @partners However unless the input corresponds with the first line, the correct information is not printed out in the while loop:
sub found { open FH, "$data" or die "Can't open $data: $!"; flock (FH, 1) or die "Can't lock $data for reading"; while (<FH>) { my ($username,$surname,$firstname,$secondname)=split (/\t/,$_); my $item = shift (@partners); if ($item eq $username) { print qq{$firstname $secondname $surname}; } } }

20040205 Edit by Corion: Added missing closing code tag

Replies are listed 'Best First'.
Re: while statement only picks up first line
by dws (Chancellor) on Feb 05, 2004 at 22:54 UTC
    However unless the input corresponds with the first line, the correct information is not printed out in the while loop

    shift is destructive on @partners. By doing the shift inside the loop, you're (probably) emptying out the array, ensuring that you'll never get a match.

    Since you intend to match against any element of @partners, try replacing your test with

    if ( 1 == grep {$_ eq $username} @partners ) {
    and remove the line that's shifting off $item.

Re: while statement only picks up first line
by graff (Chancellor) on Feb 06, 2004 at 04:40 UTC
    If I understand your intent, I think you'd be better off with a hash instead of an array for "partners" (and it would be worthwhile to get your indention into better shape):
    my %partners; $partners{$_} = undef for ( @partners ); # make a hash from your exist +ing array # (or preferably, just load your input directly into the hash, setting + the # hash keys to be the strings to look for, and the values as "undef") sub found { open( FH, $data ) or die "Can't open $data: $!"; flock( FH, 1 ) or die "Can't lock $data for reading: $!"; while (<FH>) { my ( $user, $sur, $first, $second ) = split( /\t/ ); print "$first $second $sur" if ( exists( $partners{$user} ); } }
Re: while statement only picks up first line
by jonnyfolk (Vicar) on Feb 05, 2004 at 22:56 UTC
    erm - I'm not sure you want to use shift where you do - If you've only one item in the array then by the time you come to the second pass you've emptied the array and your results will be awry.

    Update: Sorry -had to dash away...

    while (@partners){ my $item = shift (@partners); while (<FH>) { my ($usernamedb,$surname,$firstname,$secondname)=split (/\t/,$_); if ($item eq $usernamedb) { print qq{$firstname $secondname $surname}; } } }
    But this may not be very efficient...
      Um... lack of efficiency, for sure, but that's the lesser problem in this case. Your approach would involve re-reading the entire input file for each element in @partners, which is bad enough, but then you forgot to "seek FH, 0, 0" after (or before) the embedded while loop that reads the file, so there would be nothing left to read when looking for the second element in @partners.

      Doing "grep ..., @partners" for every line of the input file (as suggested in an earlier reply) is also a bit short on efficiency, if @partners has a lot of elements. Based on what the OP seems to be trying to do, a hash would be better than an array:

      ... print ... if ( exists( $partners{$usernamedb} ));
Re: while statement only picks up first line
by stvn (Monsignor) on Feb 05, 2004 at 22:59 UTC

    There is not alot of information to go on here, the code looks fine. My best guess would be that your data file came from a Windows box, and you are running this script on a UNIX box and so <FH> does not see anymore than one line. But without more detailed info, thats all i got.

    Ignore me, I have been hacking away at C# all day long, my brain is mush.

    -stvn