Re: why need my in a foreach loop?
by ikegami (Patriarch) on Nov 28, 2010 at 04:55 UTC
|
When using strict perl requires to declare even the loop variable of a foreach loop.
It can use package variables, for starters.
our $foo;
sub f {
print("$foo\n");
}
for $foo (qw( a b c )) {
f(); # Prints a, b and c.
}
Foreach loops existed long before "my".
Why is this code not allowed?
It generates an error for all instances of $word since you never declared it and you asked to make such things errors.
| [reply] [Watch: Dir/Any] [d/l] |
|
use strict;
use warnings;
use 5.010;
our $foo = 'hello';
sub f {
print("$foo\n");
}
for my $foo (qw( a b c )) {
f();
}
--output:--
hello
hello
hello
In ikegami's example, the my is omitted in the for loop, which causes the for loop to change the global variable $foo--and the subroutine prints the global $foo (i.e. the subroutine is a closure). | [reply] [Watch: Dir/Any] [d/l] |
|
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
Re: why need my in a foreach loop?
by moritz (Cardinal) on Nov 28, 2010 at 07:47 UTC
|
use strict 'vars' basically says "all variables that you use must be declared (unless they contain :: or ').
Using a variable in a loop is not different from using a variable in an assignment: it can either use an existing one, or it can be a fresh one, declared with my.
Or put another way: use strict; forces you to be explicit about your declarations. Having some construct doing implicit declarations, at least in some circumstances, goes against the entire idea of strict.
Update: Perl 6 gets around this by having other declarative syntax forms. Signatures can be used for that, either by being attached to a routine, or in the form of a lambda:
# | declares $x in the scope of the block
my $lambda = -> $x { $x * $x }
# reused in loop syntax:
for <a b cd> -> $x { say $x }
# | declares $x in the scope of the block
sub square($x) { $x * $x }
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] |
|
for @names -> $n {
say $n;
}
Why not backport that feature into Perl5. Maybe only if warnings and strict and features are full on.<?p>
As Occam said: Entia non sunt multiplicanda praeter necessitatem.
| [reply] [Watch: Dir/Any] [d/l] |
Re: why need my in a foreach loop?
by JavaFan (Canon) on Nov 28, 2010 at 12:08 UTC
|
In the old days of perl5,
foreach my $var (LIST) { .. }
was a syntax error. You had to write:
my $var;
foreach $var (LIST) { .. }
or use a package variable, as pointed out earlier in this thread.
I remember the days that
foreach my $var (LIST) { .. }
was actually seen as progress... | [reply] [Watch: Dir/Any] [d/l] [select] |
Re: why need my in a foreach loop?
by PeterPeiGuo (Hermit) on Nov 28, 2010 at 06:09 UTC
|
Why not? What's the benefit of not requiring this? What's the benefit of not having consistent rule here?
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
The foreach loop always works with an alias. IMHO the variable is never connected to anything outside the for loop so the values never "leak" out of the loop. If I am mistaken, please give an example when that variable is connected to something else as well.
| [reply] [Watch: Dir/Any] |
|
|
|