http://qs1969.pair.com?node_id=542744

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

Hi all

what is happening in the below code ?
Could any one clear me with nice answers ?

#!/bin/perl -w use strict; sub readZip() { open FH, '/dev/null'; while (<FH>) { print "Got something!\n"; } } my $x = 'hi'; for ($x) { readZip(); } print "Undefined! $x\n" unless defined $x;

"Keep pouring your ideas"

2006-10-07 Unapproved by planetscape once evidence of habitual plagiarism uncovered.

Replies are listed 'Best First'.
Re: Help need in Miscellaneous code
by ikegami (Patriarch) on Apr 12, 2006 at 04:43 UTC
    • $_ is aliased to $x by the foreach loop,
    • while does not localize $_ (like foreach loops do), and
    • while (<FH>) assigns to $_.

    Fix:

    sub readZip { local $_; open local *FH, '/dev/null'; while (<FH>) { print "Got something!\n"; } }

    I localized FH as well.

Re: Help need in Miscellaneous code
by chromatic (Archbishop) on Apr 12, 2006 at 04:49 UTC

    Which part of it is confusing?

    I suspect you wonder why $x is undefined.

    The for loop sets $_, but does not localize it. readZip() reads into $_, and the last line read is undef. That's why the while loop terminates.

    for loops alias the control variable to the values iterated -- and readZip() modifies $_, which is an alias for $x within the loop. When the loop ends, $x still holds the last value assigned to $_ within the loop: undef.

    local $_; at the start of readZip() would fix this. (You also don't need the prototype.)

    Update: Removed some very unclear text, thanks to ikegami.

      "The for loop sets $_, but does not localize it."
      should read
      "The while loop sets $_, but does not localize it."

Re: Help need in Miscellaneous code
by liverpole (Monsignor) on Oct 06, 2006 at 13:04 UTC
    Originally posted here, on July 19, 2005, with the title "Is this a perl bug?", and signed by someone named "Ted":
    Why does the following program print "Undefined!"? Shouldn't the subro +utine leave the value of $x alone? (I can understand it clobbering $_, but $ +x?) #!/usr/bin/perl -w use strict; sub readZip() { open FH, '/dev/null'; while (<FH>) { print "Got something!\n"; } } my $x = 'hi'; for ($x) { readZip(); } print "Undefined!\n" unless defined $x; (I'm using perl 5.6.1)

    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/