On 4/19/07, Jenda Krynicky <[EMAIL PROTECTED]> wrote:
From: "Chas Owens" <[EMAIL PROTECTED]>
snip
> foreach is dead, long live for.
William is dead, long live Bill?
foreach and for are two names for the same thing and just as you can
call someone both William and Bill you can use foreach and for
interchangeably.
foreach(my $i = 0; $i < $whatever; $i++)
for(my $i = 0; $i < $whatever; $i++)
for my $x (@array)
foreach my $x (@array)
for (@array)
foreach (@array)
No difference to the computer. Use whichever reads best!
Yes, foreach was aliased to for for backwards compatibility, but, like
telnet and rsh, it should not be used in new code.
I would myself use "for" for the C-style loops
And this is why. As long as people think "well, I have foreach which
is for iterating and for which is for C-style loops" they will
continue to write C-style loops. C-style loops are bad. They are
there for backwards compatibility. I can't think of a single for loop
that isn't better written as a range based for loop or while loop. For
instance
standard range based loop
for (my $i = 0; $i < 10; $i++) {}
for my $i (0 .. 9) {}
often $i winds up being used as an index which just makes me cringe.
The infinite loop
for (;;) {}
while (1) {}
The reason C programmers give for using for (;;) is that it generates
less overhead on their platform, but, at least with my tests*,
while(1) is more efficient in Perl.
Weirder stuff that you only tend to see people coming from a C background do
for (my $node = $head; $node = $node; $node->next) {}
my $node = $head;
while ($node = $node->next) {}
But in Perl it is rarely necessary to do this sort of loop since most
functions return a list that can be iterated over using for:
for my $node ($head->nodes) {}
and if I use the for loop as a way to create an alias
And that is a perfectly idiomatic usage; at least until given is added
to the language (in 5.10 from what I hear).
* benchmark
Rate bare for while
bare 6754/s -- -17% -31%
for 8179/s 21% -- -17%
while 9823/s 45% 20% --
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark;
my %subs = (
for => sub { my $i; for (;;) { last if $i++ > 1_000 } },
while => sub { my $i; while (1) { last if $i++ > 1_000 } },
bare => sub { my $i; { last if $i++ > 1_000; redo } },
);
Benchmark::cmpthese(-10, \%subs);
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/