For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > October 2006 > foreach question









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author foreach question
Andy Greenwood

2006-10-31, 6:58 pm

I have a reference to an annonymous array, which I am looping through with

foreach(@$servref) {
if ( checkServer($_, $dn) ) {
push(@$goodservref, $_);
} else {
# server wasn't good. Add another item to the list
push(@$servref, newitem);
}
}

Based on certain criteria, I want to add a new item to the end of the
$servref array. Is it safe to do this inside the foreach loop? If not,
what would be a better solution?

--
I'm nerdy in the extreme and whiter than sour cream
Tom Phoenix

2006-10-31, 6:58 pm

On 10/31/06, Andy Greenwood <greenwood.andy@gmail.com> wrote:

> I have a reference to an annonymous array, which I am looping through with
>
> foreach(@$servref) {


> Based on certain criteria, I want to add a new item to the end of the
> $servref array. Is it safe to do this inside the foreach loop?


Nope; as your intuition suggested, it's bad to modify the variable
while looping over it.

> If not, what would be a better solution?


Perhaps collect any new elements into another array, then push them
onto the main array after the loop ends. But maybe there's a way to
rethink your algorithm, especially if you want to re-check the new
elements. (Maybe one array of unchecked items, and another array of
ones that are already checked?)

Hope this helps!

--Tom Phoenix
Stonehenge Perl Training
lawrence@cluon.com

2006-10-31, 6:58 pm

>
> I have a reference to an annonymous array, which I am looping through with
>
> foreach(@$servref) {
> if ( checkServer($_, $dn) ) {
> push(@$goodservref, $_);
> } else {
> # server wasn't good. Add another item to the list
> push(@$servref, newitem);
> }
> }
>
> Based on certain criteria, I want to add a new item to the end of the
> $servref array. Is it safe to do this inside the foreach loop? If not,
> what would be a better solution?



From perldoc perlsyn:

If any part of LIST is an array, foreach will get very if
you add or remove elements within the loop body, for example with
splice. So don't do that.

A solution that doesn't violate the "don't do that" rule would be to
use a while loop instead of a for loop.

You can get away with the following, so long as @$servref has no
undefined elements.

while ( my $server = shift @$servref ) {
Rob Dixon

2006-10-31, 6:58 pm

Andy Greenwood wrote:
> I have a reference to an annonymous array, which I am looping through with
>
> foreach(@$servref) {
> if ( checkServer($_, $dn) ) {
> push(@$goodservref, $_);
> } else {
> # server wasn't good. Add another item to the list
> push(@$servref, newitem);
> }
> }
>
> Based on certain criteria, I want to add a new item to the end of the
> $servref array. Is it safe to do this inside the foreach loop? If not,
> what would be a better solution?



No it isn't safe - it is specifically warned against in perlsyn:

foreach (LIST) BLOCK

If any part of LIST is an array, "foreach" will get very if you
add or remove elements within the loop body, for example with "splice".
So don't do that.

Use this instead:

for (my $i = 0; $i < @$servref; $i++) {
my $serv = $servref->[$i];
if (checkServer($serv, $dn) ) {
push(@$goodservref, $serv);
}
else {
push(@$servref, $newitem);
}
}

HTH,

Rob
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com