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]
|
|
| 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
|
|
|
|
|