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

I wonder if someone could provide me with an explanation for the following:

(I have left in my debugging print statements.)

#!/usr/bin/perl -w use strict; use CGI ':standard'; my $data="/path/data_add.txt"; my $checkthree = param('check'); my $num = param('num'); my $action = param('action'); my @line1 = (); my @line_no = (); my ($one,$two,$three,$four,$five); print header(), start_html; open (FILE,"$data") || die "whoops: $!"; while (my $line =<FILE>) { ($one,$two,$three,$four,$five) = split "\t",$line; if (($action eq 'Put') && ($three eq $checkthree)) { $five = $five + $num; print "we have $five on line $.<br>"; @line1 = ($one,$two,$three,$four,$five); push (my @line_no, $.); print "Did this work @line_no<br>"; last; } elsif (($action eq 'Take') && ($three eq $checkthree)) { $five = $five - $num; @line1 = ($one,$two,$three,$four,$five); push (@line_no, $.); last; } } close FILE; if ($five < 0) { print "message: can't do this"; } else { my $line1 = join "\t", @line1; print "taking it out of the loop we have @line_no<br>"; my $line_no = join " ", @line_no; print "we have $five on line $line_no<br>"; open (FILE,"$data") || die "whoops 1: $!"; my @all=<FILE>; close (FILE); $all[$line_no-1] = $line1; open (FILE2,">$data.tmp") || die "whoops 2: $!"; foreach my $line (@all){ $line=~s/\n//g; print FILE2 "$line\n";} close(FILE2); rename("$data.tmp", "$data") || die "whoops 3: $!"; print "the field now contains: $five"; } print end_html();

My first question is:
having declared

my @line1 = (); my @line_no = ();
I had expected both values to exit the loop - only @line1 does.
(The print statement in the loop shows that @line_no works properly there).
Why is it subsequently unseen, and what can I do to remedy this?
Thanks very much.

Replies are listed 'Best First'.
Re: Picking up information coming out of a loop
by slife (Scribe) on Dec 12, 2002 at 12:39 UTC

    You are creating a lexically-scoped variable @line_no within your while() loop with this:

    push (my @line_no, $.);

    Should be
    push (@line_no, $.);

    as per the elsif() later within the block.

Re: Picking up information coming out of a loop
by Abigail-II (Bishop) on Dec 12, 2002 at 12:42 UTC
    push (my @line_no, $.); creates a new lexical scoped @line_no, which has no relation to the @line_no defined outside of the enclosing block.

    Next time, please, please indent your code logically, and trim down your program to just a few, relevant, lines. You might actually have solved the problem yourself by going through a reduction process.

    Abigail

      Ouch! Bottom smacked!
      thanks for your help slife, Abigail-II.

      is there an official guide to indentations? It's all a bit of a mystery to me

      I certainly would have reduced it further if I was sure where the problem is.
      (Every day in every way I will get better and better!)

        You may wish to look at Perltidy. No personal experience, but others have spoken highly of it.