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

So I was writing up a post about why a particular while statement was not getting executed while (forgive the pun) an equivalent foreach loop was when I realized my mistake.

I was operating with a scalar value not a list. Which led me to peer furthur into the depths of foreach, out of curiosity...



# foreach operating on a scalar:
my $scalar; foreach ($scalar) { print "\$scalar = $_\n"; } print "_END_\n";
Prints:
$scalar = _END_


# foreach operating on an array (list context):
my @array foreach (@array) { print "\$array[x] = $_\n"; } print "_END_\n";
Prints: _END_

# foreach operating on an array with first element defined as empty:
my @array $array[0] = ""; foreach (@array) { print "\$array[x] = $_\n"; } print "_END_\n";
Prints:
$array[x] = _END_


It starts to make sense (kind of) when you add another element...

# foreach operating on an array with two elements. first element defined as empty:
my @array $array[0] = ""; $array[1] = "foo"; foreach (@array) { print "\$array[x] = $_\n"; } print "_END_\n";
Prints:
$array[x] = $array[x] = foo _END_

Thought it might be of interest...
-Matthew

Replies are listed 'Best First'.
RE: While Vs. Foreach
by mikfire (Deacon) on Jul 18, 2000 at 22:03 UTC
    And another mendicant friar is tripped on the difference between undef, an empty string, spaces and stuff. Please allow me to demonstrate my pale understanding of the mysteries you have encountered.

    In perl, when you say

    my $foo;
    Perl is very nice and assigns it a very unique value - undef. The "value" undef is kind of strange, it is the sound of one hand clapping ( or my jaws flapping, if prefer ).

    When you said

    foreach ( $foo ) { print "$_\n"; }
    you created an anonymous array with exactly one element, and the "value" if that element was undef. When you try to print undef ( especially when not using -w ;/ ), perl prints nothing.

    When you say

    my @foo;
    Perl is very kind and creates and empty array. This is very different from an array whose only element is undef. So when you said
    foreach ( @foo ) { print "array[x] = $_\n"; }
    perl tested @foo, found no elements and passed on. It is even possible the branch was compiled out - ie, the interpreter never even saw it.

    When you then said

    my @array $array[0] = "";
    You created an array with one element, and the value of that element was the empty string. This is very different from creating an element whose value was undef. This form will not generate a warning, had you been using -w ;/ Thus, when you went to print, you printed an empty string which does, coincidentally look an awful lot like printing undef. Unless one is using -w ;/

    Of course, your last example was nothing but an extension of the previous and I have covered that. Except I feel the overwhelming urge to mention you didn't use -w ;/

    The emptry string is not the same as undef. An empty array is not the same as an array whose first element is either the empty string or undef. But most of all, my fellow monk, use -w. This is exactly the kind of pain -w was intended to stop. Because one day you will type $from when you meant $form and things won't work. -w is the only thing between you and possibly days of fruitless bug chasing.

    The correct invocation for perl is

    #!/path/to/your/perl -w use strict;
    Trust me. mikfire