tags:

views:

112

answers:

5

Hello! I remember something about not changing the keys in a

for my $key ( keys %hash ) { ...

for example

for my $key ( keys %hash ) {
    $key = "$key_x";
}

But deleting keys and changing values would be fine. Are my memories OK?

A: 

But , if you want change key name .

you can delete the keys from hash , then create the key with exist values as you want. this could be a one work around for this requirement

pavun_cool
+3  A: 

See the keys function manpage:

The returned values are copies of the original keys in the hash, so modifying them will not affect the original hash. Compare "values".

You can delete or change hash elements by subscripting, e.g.

delete $hash{$key};
$hash{$key} = "foo";
eugene y
+1  A: 

you cannot rename any key value instead you can delete and create a new one which is not lesser than renaming a key! :-)

for my $key ( keys %hash ) {
    delete $hash{$key}; 
    $hash{$key} = "$key_x";
}
abubacker
abubacker's statement is correct (and important, and not explicitly said in the accepted answer), though it doesn't have anything to do with the loops; why the downvotes? the example should probably be $hash{$newkey} = delete $hash{$key} though.
ysth
@ysth Thought he must be a beginner don't want to confuse him , some times we mustn't always think in our point of view my friend,hope u'll change the down votes :-)
abubacker
+2  A: 

The way to do this would be

$hash{$newkey} = delete $hash{$oldkey}; 
Leon Timmermans
+7  A: 

I think what you're remembering is the fact that if you do

for my $item (@array) {
    ...
}

then adding or removing items in the middle of @array (for instance by using splice) is disallowed, and the result if you try it is undefined. In fact, in olden days you could actually crash perl that way.

Since the list returned by keys is a copy, it's determined entirely at the moment the loop starts, and adding and removing keys from the hash won't affect the loop at all. That means that you can do things like

for my $key (keys %hash) {
    $hash{lc $key} = delete $hash{$key};
}

100% safely without worrying. I can promise this is true back to perl 5.6.1 (April 2001), which was when the note that "the returned values are copies" was added to perlfunc, but it seems that it's been so since forever, and the change was only to the docs.

Since $key in the loop is aliased to a value in a temporary list, you can change it without anything bad happening, but it won't have any effect on %hash at all.

hobbs
Or sid_com is remembering for ... ( ... each %hash ) { ... modify %hash ... }
ysth