[Israel.pm] Can anyone explain my mistake ?

sawyer x xsawyerx at gmail.com
Wed Jun 10 06:24:17 PDT 2009


As usual, other people gave interesting insight into things.
I personally would like to comment on something else.

2009/6/10 Berler Chanan <chananb at centerity.com>
>
> In the real world (in my way of thinking)
> Foreach should have interpreted into a 'for' loop
>
> Means:
> foreach $elm (@elm_arr) ==> should have been: for ($index = 0; $index >=
> $#elm_arr; $index++) { $elm = $elm_arr[$index]; ..... }
>
> this way my script would have worked.
> Chanan

That's an interesting way to look it. But, you're forgetting that with
foreach you iterate over scalars which is much more dynamic. In a
traditional for loop (which Perl, as shown, supports completely) you
iterate (at least in your example, and the behavior you expected) over
an index variable.
Your assumption was that the index variable represents (at the same
time) the actual element in the array in each iteration, which isn't
always the case. I'm not sure I'm being clear on this.

Basically there are two things to take into account when iterating
over an array:
- The iteration (the position you are in when going over the array)
- The array element in that position

Meaning, in oldschool C for loop, you have an index and then you fetch
the element that is in that in index. You're in $i = 2 (or i =2, in
C), and you fetch $elem_array[$i]. This has major setback, especially
in your case. In your case, the value of the elements are the index
themselves which is, not just counterintuitive, but can provide an
error. Usually counting starts at 0, your first array element is 1.
You have an off-count.
Foreach loop tries to address it by being smarter. You don't need the
index with the foreach loop. It fetches the value for you (actually,
an alias to the value - an important distinction Gabor did) and
provides you with a codeblock to edit it. That way, you don't have to
mess with the index iteration and just handle the code you're running.
Of course, it also allows the regular C style for loop, but usually
there's no point for it. Here is a way to run an index iterator as
you're used to in C, using foreach:
foreach my $i ( 0 .. $#array ) {
  my $val = $array[$i];
  print "my val: $val\n";
}

However, if all I need is the value, and not the index iterations, the
Perl style is much simpler (read: direct, readable, maintainable):
foreach my $val (@array) {
  print "my val: $val\n";
}

An important point I forgot to mention (boy, this is long), is the
question "what if you wish to iterate over strings, not numbers?" If
your @array has ("word1", "word2", "two words", "more stuff"), you
can't do $index++.

By iterating over the values (and not giving you an index of the
values that is autoincremented - while assuming it's a number), you
have much more flexibility.

If anyone wants to refute any of these claims, you're more than
welcome and I could be wrong about this, or anything else, for that
matter.


More information about the Perl mailing list