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

#!/usr/bin/perl #===================================================================== +========== # # FILE: test.pl # # USAGE: ./test.pl # # DESCRIPTION: # # OPTIONS: --- # REQUIREMENTS: --- # BUGS: --- # NOTES: --- # AUTHOR: YOUR NAME (), # COMPANY: # VERSION: 1.0 # CREATED: 2012/3/9 &#19979;&#21320; 03:23:45 # REVISION: --- #===================================================================== +========== use strict; use warnings; system("ls > z & ls > zz"); my $a = "z"; my $b = "zz"; foreach($a,$b) { print $_; my $fh; open $fh,"<$_"; while(<$fh>){ print $_; } close $fh; } print $a,$b;
when i run this code i lost $a and $b value
my perl version is v5.10.1 built for MSWin32-x86-multi-thread

Replies are listed 'Best First'.
Re: the variable is lost
by JavaFan (Canon) on Mar 09, 2012 at 10:43 UTC
    foreach ($a, $b)
    This makes $_ an alias to $a and $b.
    while (<$fh>)
    This modifies $_, and hence, modifies $a and $b. Note that the final value will be undefined.
Re: the variable is lost
by davido (Cardinal) on Mar 09, 2012 at 08:14 UTC

    So what output did you get?

    It might help to verify the return value of open, as in, "open $fh, '<', $_ or die $!;" so you'll know if the open is failing.


    Dave

      when i run code i get two warning
      Use of uninitialized value $a in print at D:\test.pl line 38.
      Use of uninitialized value $b in print at D:\test.pl line 38.

        I only see 19 lines of code. Which line is #38?

        Update: Thanks for clarifying your code now.

        Your while loop is reading <$fh> into $_, which is clobbering your foreach loop's version of $_. Since the topic variable in a foreach loop aliases the elements you're iterating over (ie, $a and $b), clobbering $_ clobbers $a and $b.

        Use an explicitly named topic variable for your foreach loop.


        Dave

Re: the variable is lost
by ikegami (Patriarch) on Mar 09, 2012 at 22:59 UTC
    while(<$fh>)
    is short for
    while(defined($_ = <$fh>))

    and $_ is aliased to $a and $b in turn by the foreach loop. Every time you change $_ by assigning a line to it, you change the value of $a or $b.

    Solution: Change

    while(<$fh>){ print; }

    to

    local $_; while(<$fh>){ print; }

    or

    while(my $line = <$fh>){ print $line; }

    By the way, because $a and $b have special meaning to sort, one usually avoids them. my $a and my $b can actually cause sort to malfunction.

Re: the variable is lost
by Anonymous Monk on Mar 09, 2012 at 08:32 UTC

    I don't know what's causing this, but you should stay away from $a and $b as variable names, as they are reserved for sort (perlvar).

    Furthermore, I don't understand why you are using unix commands in system() despite running on windows.

      the question is not the variable's name.
      when i change variable name warning still exist
      install gnuwin32 you can use ls command in windows

        FWIW, using $a and $b outside of sort is always a mistake