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

HI Monks;

I want to make variable to forget its previous value while running in loop. I tried reset, delete but its not working. here is something like this troubling me:

use List::Util qw/ min max sum /; $a = -55;$b = -54; $c = -55;$d = -54; for (1..110) { $file = "x_$a\_to_$b\_y$c\_to_$d";#file name open(INFILE,"<","$file") or die("Couldn't open file for reading!\n"); while(<INFILE>){ push @column8,(split(/\s+/,$_))[7]; } $ZMAX = max @column8;print "maxZ $ZMAX\n"; $ZMIN = min @column8;print "minZ $ZMIN\n"; $thick = $ZMAX - $ZMIN; print "$thick\n"; $c++; $d++; }

Some of my files are empty or have single value from where it gives maximum and minimum difference as none or zero.So, actually when I run loop to calculate difference between maximum and minimum values for each file and if Zmax or Zmin is not found in the next file it uses previous file values. So is it possible to make Zmax or Zmin forget about existence after finishing one loop, so that in next loop it acts like a new variable again?

Replies are listed 'Best First'.
Re: how to make variable forget its previous value?
by AnomalousMonk (Archbishop) on Jan 03, 2012 at 08:49 UTC

    I do not clearly understand what you are trying to do, but it looks as if you want to extract the values of column 8 in each file individually and find the minimum and maximum of these values per file and compute some other value or values.

    In the OPed code, the array  @column8 is automatically created and values from all files are pushed to it. The array is never cleared from file to file. The problem seems to me to be with this array and not with the  $ZMAX and  $ZMIN scalar variables.

    I think I would write something along the lines of the following untested code. Lexical variables are used everywhere. Warnings and strictures are enabled. A new array is created for each file.

    use warnings; use strict; use List::Util qw/ min max sum /; my $a = -55; my $b = -54; my $c = -55; my $d = -54; FILE: for (1..110) { my $file = "x_$a\_to_$b\_y$c\_to_$d"; open(my $in_fh, '<', $file) or die "opening '$file': $!"; my @column8; # FRESH, NEW, EMPTY ARRAY for each file! while(<$in_fh>){ push @column8, (split(/\s+/, $_))[7]; } next FILE if @column8 < 2; # are min/max valid? my $ZMAX = max @column8; my $ZMIN = min @column8; my $thick = $ZMAX - $ZMIN; print "$thick\n"; $c++; $d++; }

    BTW: Another way to make an array 'forget' its previous contents is to clear the array by assigning the empty list to it:
        @column8 = ();

      Thanks to all awesome MONKS;

      I got it solved :-) Yes one monk (anonymous) suggested ">>The array is never cleared from file to file". This thing worked for me. so my final code is (am not using all suggestions, so following codes work fine)

      use warnings; use strict; use List::Util qw/ min max sum /; my $a = -55; my $b = -54; my $c = -55; my $d = -54; for (1..110) { my $file = "x_$a\_to_$b\_y$c\_to_$d"; open(my INFILE, '<', $file) or die "opening '$file': $!"; my @column8; # FRESH, NEW, EMPTY ARRAY for each file! ## YES defining here again my @column8 is very good while(<INFILE>){ push @column8, (split(/\s+/, $_))[7]; } $ZMAX = max @column8; $ZMIN = min @column8; $thick = $ZMAX - $ZMIN; print "$thick\n"; $c++; $d++; }

      thanks to all other monks also

        open(my INFILE, ... ... while(<INFILE>){ ...

        If using a lexical filehandle, this should be
           open(my $INFILE, ...
        and
            while(<$INFILE>){ ...
        (scalar  $INFILE rather than  INFILE).

        Update: Also, I think you still need a test to specially handle the cases of files with zero or one records, e.g., (still untested)
            next FILE if @column8 < 2;  # are min/max valid?
        from my original reply.

Re: how to make variable forget its previous value?
by Anonymous Monk on Jan 03, 2012 at 05:36 UTC
Re: how to make variable forget its previous value?
by locked_user sundialsvc4 (Abbot) on Jan 03, 2012 at 14:44 UTC

    I would follow both pieces of advice:

    1. Define variables locally, and within the tightest possible scope, not merely to cause them to be reinitialized but also to limit their visibility to the rest of the program.   If a variable could have an uninitialized or, worse yet, a “stale” value when accidentally seen from the wrong nearby place, eliminate such an “accident” as a possibility and turn it into a compile-time error.   (use strict; use warnings;)   Use the variable-name only once in a particular region, to avoid human-confusion, then set the lexical boundaries as tightly as makes sense, thereby maximizing the computer’s ability to stupid detect misteaks which you you will overlook...
    2. If you need to return a variable to its initial (undefined) state, use undef.   (Notice that in Perl this is not the same as a “null,” “nil,” or “empty” value.)

Re: how to make variable forget its previous value?
by sharief (Novice) on Jan 03, 2012 at 10:30 UTC

    Hi,

    Note i am not sure about what you asked us exactly may be if this code is wrong i am sorry about that

    Update sorry about the above code i din notice the while loop in between so make this alteration

    use List::Util qw/ min max sum /; $a = -55; $b = -54; $c = -55; $d = -54; for (1..110)# Start your loop { $file = "x_$a\_to_$b\_y$c\_to_$d";#file name open(INFILE,"<","$file") or die("Couldn't open file for reading!\n"); while(<INFILE>){ push @column8,(split(/\s+/,$_))[7];##Push data to array } if(@column8)## if array is not empty then it will go inside { $ZMAX = max @column8; print "maxZ $ZMAX\n"; $ZMIN = min @column8; print "minZ $ZMIN\n"; $thick = $ZMAX - $ZMIN; print "$thick\n"; } ## Once the values are printed this will help you to erase the previou +s values of $ZMAX, $ZMIN, $thick, @column8 for your second file $ZMAX=""; $ZMIN=""; $thick=""; @column8=(); $c++; $d++; ## Note this loop will run for 110 times so it seems you should have 1 +10 files when you increment $c++ and $d++; }
      for (1..110) { ......//Only when this loops ends you are assigning zmax } $ZMAX = max @column8; print "maxZ $ZMAX\n"; $ZMIN = min @column8; print "minZ $ZMIN\n"; $thick = $ZMAX - $ZMIN;

      The OPed code actually assigns  $ZMAX etc. within the body of the for-loop.