Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Hash value modification

by Tanalis (Curate)
on Jul 25, 2005 at 07:54 UTC ( #477712=perlquestion: print w/ replies, xml ) Need Help??
Tanalis has asked for the wisdom of the Perl Monks concerning the following question:

Update: Some more digging and I've answered my own question: Old Perl Behavior(TM). This behaviour was changed in Perl 5.6.1 (changelog) to make access to hash elements faster. More ammunition for the Update the Perl Version Campaign ... :)
I've been bitten this morning by some interesting behaviour when performing regular expression substitution on the values of a hash.

I'm used to being able to do something like

foreach( @array ) { s/something/something_else/g }
to an array, and expected a similar thing to work for hashes:
foreach( values %hash ) { s/something/something_else/g }
but it appears that this isn't the case. The substitution is performed, but on a copy of the original value, not a reference to it. Of course,
foreach( keys %hash ) { $hash{$_} =~ s/something/something_else/g; }
works as expected.

This interests me, and appears a little inconsistent. Is there some reason that my coffee-deprived brain can't see this morning for this inconsistency to exist?

Comment on Hash value modification
Select or Download Code
Re: Hash value modification
by sk (Curate) on Jul 25, 2005 at 08:08 UTC
     perldoc -f values

    Note that the values are not copied, which means modifying them will modify the contents of the hash:

    for (values %hash) { s/foo/bar/g }   # modifies %hash values

    Can you give an example on what you are seeing?

    SK

    Update: Are you not seeing this behavior?

    #!/usr/bin/perl -w my @array = qw(1 hello 2 hello 3 hellome 4 hellothere); my %hash = @array; foreach( values %hash ) { s/hello/hi/g; } print +("$_ = $hash{$_}\n") for (sort keys %hash);

    Output

    1 = hi 2 = hi 3 = hime 4 = hithere
Re: Hash value modification
by SimonClinch (Chaplain) on Jul 25, 2005 at 08:57 UTC
    Here's a test, which shows the same behaviour happening as for arrays:
    #!/usr/bin/perl use Data::Dumper; my %h = ( aa => hello, bb => ghello ); foreach ( values %h ) { s/el/ig/g }; print Dumper( \%h );

    Output:

    $VAR1 = { 'aa' => 'higlo', 'bb' => 'ghiglo' };

    One world, one people

Re: Hash value modification
by siliconGopher (Initiate) on Jul 25, 2005 at 12:21 UTC
    Im not sure I understand the inconsistancy. I performed similar operations on both, a hash and an array and I found the results as expected. Using the following code.

    #!/usr/bin/perl use Data::Dumper; my %hash = ( b => bell, c => cell, d => dell, f => fell, h => hell ); foreach ( values %hash ) { s/ell/it/g }; print Dumper( \%hash ); my @array = qw ( b bell c cell d dell f fell h hell ); foreach ( @array ) { s/ell/it/g }; print Dumper ( \@array );
    The results were as follows,
    $VAR1 = { 'c' => 'cit', 'h' => 'hit', 'b' => 'bit', 'd' => 'dit', 'f' => 'fit' }; $VAR1 = [ 'b', 'bit', 'c', 'cit', 'd', 'dit', 'f', 'fit', 'h', 'hit' ];

    Wisdom:For every problem, there is a solution that is simple, neat and wrong.
Re: Hash value modification
by tlm (Prior) on Jul 25, 2005 at 12:34 UTC

    FWIW, slices also work:

    for ( @hash{ keys %hash } ) { s/something/something_else/g; }

    the lowliest monk

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://477712]
Approved by jbrugger
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (16)
As of 2014-09-17 13:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (81 votes), past polls