legLess has asked for the wisdom of the Perl Monks concerning the following question:

Monks ~

I'm trying (for readability's sake) to assign a branch of a nested hash to a new hash variable. I've solved my problem, but maybe I can decrease my Perl purity and solve it a different way next time. Here's a simplified version of the code:

# main nested hash my %pages = ( add_event_type => { show => { template => "add_evt", first_control => 'event_type_name', data => { event_type_name => { type => 'text', req => 1 }, event_type_description => { type => 'text' }, }, }, }, ); # elsewhere my $page = "add_event_type"; my $action = "show"; # the code in question my %page = %{ $pages{ $page }{ $action }}; # which allows, later my $first_control = $page{ first_control }; # instead of my $first_control_again = $pages{ $page }{ $action }{ first_control };

--
man with no legs, inc.

Replies are listed 'Best First'.
Re: Getting a branch of a nested hash
by dragonchild (Archbishop) on Jan 27, 2003 at 18:48 UTC
    Looks good to me.

    Note: my %page = %{ ... }; is making a copy of the hash. Changes will not be retained. If you are changing that branch and want your changes to stick around, you will need to do something like my $page = ...; and $page->{first_control} = 'foo';

    As a rule of thumb, if you already have the reference, just use it, unless you don't want to change it and should copy it.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      Note: my %page = %{ ... }; is making a copy of the hash. Changes will not be retained.
      Are you sure? Try running this:
      #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my %hash = (key1 => { subkey1 => [ qw(a number of elements in an array) + ], }, key2 => "value2"); my %hash2 = %hash; $hash2{key1}->{subkey1} = [ qw(other elements in an array) ]; print Dumper(\%hash); print Dumper(\%hash2);
      A hash copy will only do a shallow copy, i.e. the references are copied instead of the contents of those references. That's why changes to %hash2 also end up in %hash. Using Devel::Peek to display %hash and %hash2 will make this even more clear. Search for the lines looking like:

      Elt "key2" HASH = 0x3e4d4a SV = PV(0x80f6498) at 0x81009c4

      and note the addresses.

      Arjen

        Kinda sorta not really. It all depends on whether what you're modifying is the stuff in the hash you copied or in child hashes. Let's say you have:
        my %hash = ( key1 => { a => 1, b => 2, }, key2 => 'blah' ); my %hash1 = %{ $hash{key1} }; $hash1{a} = 3; # This change persists $hash1{c} = 5; # This change does NOT persist
        It all depends, doesn't it? :-) (And also why objects should encapsulate this crap.)

        ------
        We are the carpenters and bricklayers of the Information Age.

        Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.