On Jun 24, 2005, at 5:07, Anthony Roe wrote:
A = Reads URI from URIHASH.
Visits site A.
Parses all URIS on site A and for each URI found adds the URI to
the URIHASH.
A = Reads next URI from URIHASH.
Visits site A.
And so on... until the MAX URIHASH size is reached.
My question is, is there any way to iterate through a hash in this
manner.
I tried foreach():
foreach $key (keys %URIHASH){}
You don't see the changes because
keys %URIHASH
returns the list of keys *once*, when the foreach is entered. That
list is kept in memory, it is not recomputed in each iteration. So
you are modifying %URIHASH just fine, but iterating over the old list
of keys.
and this does not work. What occurs is the entry that exists in the
URIHASH when the foreach loop is entered, is processed.
any additional entries that are added during the loop are not
processed.
I also tried each():
When a program iterates over a hash it can't modify it. That's the idea.
That happens in general to collections no matter the programming
language because of their underlying implementations and the ones for
iterators. One needs to check the documentation about it to see
what's allowed in each case.
When you are iterating in Perl over a hash with each(), the only
valid modification (and so an exception to the rule stated above) is
a case of delete. From perldoc -f each:
If you add or delete elements of a hash while you're
iterating over it, you may get entries skipped or duplicated,
so don't. Exception: It is always safe to delete the item most
recently returned by "each()", which means that the following
code will work:
while (($key, $value) = each %hash) {
print $key, "\n";
delete $hash{$key}; # This is safe
}
A solution for your program is to maintain some sort of auxiliar hash
or array, sometimes it makes sense to merge it with the hash after
each iteration, sometimes not, depending on the program. For
instance, something like this:
my @uris = keys %URIHASH;
while (@uris) { # checks size, no problem
my $uri = shift @uris; # short @uris by one
push @uris, @newuris; # add uris to the array
@[EMAIL PROTECTED] = (1) x @newuris; # merge them in the hash
}
That's an example, but anyway you see why this happens and what needs
to be fixed.
-- fxn
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>