in reply to (s)coping with foreach

You best off keeping $var in the scope of the loop:
for my $var (0..9){ #UPDATE: I changed 1-9 to 0-9 print $var; } #actually, this is better . . . but I digress . . . print (0..9);
No need to declare $var and assign zero to it like you did in the first example. There really is no need to keep $var around after you have finished the loop. If you need to remember what it was, look at the array you were looping through. Rarely are you going to say (1..9) in any serious program, unless you love playing catch-up to scalability:
my @numbers = (0..9); foreach my $n (@numbers) { print $n; } print "\n", scalar(@numbers), "\n";
will produce
0123456789 10
As for why this:
my $var; for ($var=1; $var < 10; ++$var){ print $var; } print "\n", $var, "\n";
yields $var = 10 after it finishes, the reason is because that's how a C-style for loop works. Think about it. It _HAS_ to be 10, because $var increments 1 at a time . . .
and in order for the loop to stop . . . .
$var has to be equal to 10 . . . ;)

Jeff

R-R-R--R-R-R--R-R-R--R-R-R--R-R-R--
L-L--L-L--L-L--L-L--L-L--L-L--L-L--

Replies are listed 'Best First'.
Re: (jeffa) Re: (s)coping with foreach
by greenFox (Vicar) on Apr 02, 2001 at 07:07 UTC

    The somewhat strange syntax was to demonstrate the localisation of the index variable which I wasn't aware of :) As to using why you would want to do this, if you exit the loop at any point before the final iteration the count of elements may not be useful but the last value of the index variable will tell you when you left... no doubt there are better ways to do the same thing but I wasn't playing with production code I was just playing and I noticed something I didn't expect :)

    the c-style loop still bothers me, OK I can now see why it is greater than the last increment but it seems wrong that the variable contains this value outside of the loop when you have explicitly asked it to stop before you got there! Of course if I used the loop as intended I would never have noticed... or if the index variable was localised as in the perl style loop.

    --
    my $chainsaw = 'Perl';

      ...the last value of the index variable will tell you when you left...
      then try this:
      my @numbers = (0..9); foreach my $i (0..$#numbers) { print $numbers[$i]; stopped($i),last if $i > 4; } sub stopped { my $index = shift; print "Stopped at $index\n"; }

      Jeff

      R-R-R--R-R-R--R-R-R--R-R-R--R-R-R--
      L-L--L-L--L-L--L-L--L-L--L-L--L-L--
      
Re: (jeffa) Re: (s)coping with foreach
by extremely (Priest) on Apr 02, 2001 at 00:31 UTC
    i think the point of that last bit was that "foreach" and "for" act differently. Foreach localizes the $var and for doesn't. And that after people keep telling you that they are the same thing and you can use "for" for "foreach" =)

    --
    $you = new YOU;
    honk() if $you->love(perl)

      Says extremely:
      i think the point of that last bit was that "foreach" and "for" act differently.
      Definitely wrong. for and foreach are completely identical. Once Perl finishes compiling your program, it can't even remember which one you used.

      If you look in toke.c, you will see:

      case KEY_for: case KEY_foreach: ... code here that handles 'for' and 'foreach'
      This is in the vicinity of line 4145.
      Err,

      Do they? According to the camel:

      "The foreach keyword is actually a synonym for the for keyword, so you can use foreach for readability or for for brevity."

      - p100, Programming Perl, 2nd edition

      .02

      cLive ;-)

      Well that wasn't the point I was trying to make :) I tried this though
      my $var=0; foreach ($var=1; $var < 10; ++$var){ print $var; } print "\n$var \n";

      it appears that when used with a c style loop for/foreach does not localise the index variable... and for the record I have never written a loop with the index variable other than the normal syntax of for (my $var;... :-)

      --
      my $chainsaw = 'Perl';

        "Well that wasn't the point I was trying to make :)"

        I know, but... hmmm.

        Getting back to your questions...

        Let's rewrite your loop:

        my $var=0; { $var=1; while ($var < 10) { print "$var"; $var++; } } print "\n$var \n";

        The for loop adds to $var, then checks condition, then breaks loop. It doesn't say would I break the condition if I added one to $var, so $var is 10.

        Also, you don't declare $var as being local to the loop. So, look at this:

        my $var=0; foreach (my $var=1; $var < 10; ++$var){ print $var; } print "\n$var \n";

        Or, as written above:

        my $var=0; { my $var=1; while ($var < 10) { print "$var"; $var++; } } print "\n$var \n";

        Seem clearer now?

        cLive ;-)