I have on occasion had the need to dig down into a complex data structure to change a key (e.g. s/SOMEKEY/SomeKey/, etc. ). The usual digging approach is using loops. Here is a useful trick using a serialized data structure that has saved me some time here and there:
use YAML::XS; my $yaml = Dump $hash; $yaml =~ s/SOMEKEY/SomeKey/; $hash = Load $yaml;
I posted this on Stack Overflow to an old question, but it didn't get many votes. So either it's a bad idea or the question was too old. Anyway, I post it here because I like this trick. Clearly, you should dump the structure and be sure that your replacement won't mess something else up. With power comes responsibility...

Replies are listed 'Best First'.
Re: Using serialized data structure to change hash key
by Athanasius (Archbishop) on Mar 18, 2015 at 14:32 UTC

    Hello docdurdee,

    The problem with this approach is that SOMEKEY might also appear elsewhere in the hash: as a substring of another key, or as a value. The first case can be tackled by adding word boundaries to the regex: $yaml =~ s{\bSOMEKEY\b}{SomeKey}. But I don’t see any obvious solution to the second case:

    #! perl use strict; use warnings; use Data::Dump; use YAML::XS; my $hash = { Fred => 'Wilma', Frederick => 'Mary', Barney => 'Fred' }; my $yaml = Dump $hash; $yaml =~ s/\bFred\b/FRED/; $hash = Load $yaml; dd $hash;

    The output I (happen to?) get:

    0:26 >perl 1186_SoPW.pl { Barney => "FRED", Fred => "Wilma", Frederick => "Mary" } 0:30 >

    Of course, you can add a /g modifier to the substitution, but you’ll still get the value changed as well, when you don’t want it to be. :-(

    Update: On second thought, I think this should work for most cases:

    $yaml =~ s/(?<=\n)Fred(?=:)/FRED/g;

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Thanks Athanasius! The last two sentences of the meditation were intended to express that care would be needed to actually us this trick. Thank you for providing the potential pitfalls. The described trick has made my life much easier more than once when working with some data stored in a hash, but I was very familiar with the data (even if the data structure had gotten a little out of hand).
Re: Using serialized data structure to change hash key
by Arunbear (Prior) on Mar 18, 2015 at 16:03 UTC
    A safer method using Data::Diver:
    use strict; use Data::Diver 'DiveVal'; use Data::Dump 'dd'; my $root= { top => [ { first => 1 }, { second => { key => [ 0, 1, 2, { three => { exists => 'yes', }, }, ], }, }, ], }; DiveVal($root, qw/top 1 second key 3 three exists/) = 'no'; dd($root);
    Output:
    { top => [ { first => 1 }, { second => { key => [0, 1, 2, { three => { exists => "no" +} }] } }, ], }
Re: Using serialized data structure to change hash key
by vkon (Curate) on Apr 08, 2015 at 15:00 UTC
    I don't like - this dirty hack is too dirty, error-prone and unstable.
    but more to the point - why it is a problem to go deep enough to change your SOMEKEY?? Hash structure is too complicated? then you have bigger trouble than changing someKEY to SOMekeY...

    I can't imagine normal use case for the idea, so I will not drop a tear if it will be completely dumped.