why does this not work: foreach (my $word) (@word_array){...}

T

TechCrazy

Why do I have to move the declaration of $word outside like this:

my $word;
foreach $word (@word_array){
...
}

If I use inline declaration (to limit scope)

foreach (my $word) (@word_array){
...
}

the compiler gets confused.
 
A

A. Sinan Unur

Why do I have to move the declaration of $word outside like this:

my $word;
foreach $word (@word_array){
...
}

If I use inline declaration (to limit scope)

foreach (my $word) (@word_array){
...
}

the compiler gets confused.

Well, which list do you want to iterate over?

foreach my $word (@word_array) {
...
}
 
T

TechCrazy

Thanks for the helpful exposition, Tim. I didn't think the solution
would be so simple.

It would have been nice if scope of the iterator ($word) could be
limited to the foreach loop.
 
J

John Bokma

TechCrazy said:
Thanks for the helpful exposition, Tim. I didn't think the solution
would be so simple.

It would have been nice if scope of the iterator ($word) could be
limited to the foreach loop.

Read better:

for my $word ( @words ) {

}

does exactly this

my $word;
for $word ( @words ) {

}

doesn't.

In the former you can't use $word (it's gone) [1], in the latter it's
still there.

[1] the one used in the for that is.

The last form has it uses if you want to go over the list *and* keep
$word, e.g.

my $word;
for $word ( @words ) {

last if exists $foo{ $word };
}
 
J

Jürgen Exner

TechCrazy said:
@word_array

Yes, what is the matter with @word_array?
Perl variable types and syntax is explained in "perldoc perldata".

If you would provide more text then just one single word then maybe we would
know what your question is.

jue
 
N

nobull

John said:
my $word;
for $word ( @words ) {

}

doesn't.

In the former you can't use $word (it's gone) [1], in the latter it's
still there.

[1] the one used in the for that is.

Actually this is not true.

The $word inside the loop is still a different lexical variable scoped
to the block.

In effect if you say...

my $word;
for $word ( @words ) {

}

....then Perl behaves as if you had said...

my $word;
for my $word ( @words ) {

}

As I have said on a number of occasions in the past I think Perl should
emit a warning when it does this.
 
T

Tad McClellan

TechCrazy said:
It would have been nice if scope of the iterator ($word) could be
limited to the foreach loop.


The scope of the iterator *is* limited to the foreach loop in
the code given to answer your question.
 
X

xhoster

Tim Hammerquist said:
Tim Hammerquist said:
TechCrazy said:
Why do I have to move the declaration of $word outside like this:

my $word;
foreach $word (@word_array){
...
}
[ snippage ]

What you want is:

foreach my $word (@word_array) {
...
}

NB: there are subtle scoping differences between the OP's example at top
and mine. In the top, $word will still be in scope after the foreach
loop exits.

Technically, perhaps, but foreach implicitly localizes (or something
like that) the iterator. So for most intents and purposes, the iterator
is a different variable than the one that was declared before the loop.

Xho
 
X

xhoster

John Bokma said:
The last form has it uses if you want to go over the list *and* keep
$word, e.g.

my $word;
for $word ( @words ) {

last if exists $foo{ $word };
}

Alas, this doesn't keep the value in $word after "last"ing, so it doesn't
do anything very useful.

$ perl -le 'my $x=3; foreach $x (1..10){last if $x==5}; print $x'
3


Xho
 
J

John Bokma

John Bokma wrote:
The $word inside the loop is still a different lexical variable scoped
to the block.

You are right, and thanks for teaching me something :-D
As I have said on a number of occasions in the past I think Perl should
emit a warning when it does this.

I agree. Something like $word is masking early declaration of $word in for
loop.
 
J

John Bokma

Alas, this doesn't keep the value in $word after "last"ing, so it doesn't
do anything very useful.

So I understand, thanks to nobull and you for pointing this out.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top