Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^2: Building an arbitrary-depth, multi-level hash

by repellent (Priest)
on Mar 01, 2009 at 21:13 UTC ( [id://747354]=note: print w/replies, xml ) Need Help??


in reply to Re: Building an arbitrary-depth, multi-level hash
in thread Building an arbitrary-depth, multi-level hash

Or more concisely:
my $p = \\%hash; $p = \$$p->{$_} for @cats; $$p->{_val} = $value;

See Re: Autovivification trick. The form:
$p = \$$p->{$_} ...

does not leave around refs to empty hashes (it leaves undef's instead).

But seriously, use Data::Diver.

Replies are listed 'Best First'.
Re^3: Building an arbitrary-depth, multi-level hash
by ikegami (Patriarch) on Mar 01, 2009 at 21:26 UTC

    does not leave around refs to empty hashes (it leaves undef's instead).

    What does that mean? In fact, vivification is required here.

    use strict; use warnings; use Data::Dumper qw( Dumper ); sub samtregar { my $p = shift; my $val = pop; for my $item (@_) { $p->{$item} ||= {}; $p = $p->{$item}; } $p->{_val} = $val; } sub repellent { my $p = \shift; my $val = pop; $p = \$$p->{$_} for @_; $$p->{_val} = $val; } { samtregar(my $samtregar={}, qw( a b c d ), 'foo'); repellent(my $repellent, qw( a b c d ), 'foo'); { local $Data::Dumper::Useqq = 1; local $Data::Dumper::Terse = 1; local $Data::Dumper::Indent = 0; print("samtregar: ", Dumper($samtregar), "\n"); print("repellent: ", Dumper($repellent), "\n"); } }
    samtregar: {"a" => {"b" => {"c" => {"d" => {"_val" => "foo"}}}}} repellent: {"a" => {"b" => {"c" => {"d" => {"_val" => "foo"}}}}}

    And for a getter, what you said is backwards. Yours is the one that vivifies.

    use strict; use warnings; use Data::Dumper qw( Dumper ); sub samtregar_fetcher { my $p = shift; for my $item (@_) { last if !$p->{$item}; $p = $p->{$item}; } return $p->{_val} } sub repellent_fetcher { my $p = \shift; my $val = pop; $p = \$$p->{$_} for @_; return $$p->{_val}; } { samtregar_fetcher(my $samtregar={}, qw( a b c d )); repellent_fetcher(my $repellent, qw( a b c d )); { local $Data::Dumper::Useqq = 1; local $Data::Dumper::Terse = 1; local $Data::Dumper::Indent = 0; print("samtregar: ", Dumper($samtregar), "\n"); print("repellent: ", Dumper($repellent), "\n"); } }
    samtregar: {} repellent: {"a" => {"b" => {"c" => {}}}}
      Sorry, I was too brief. What I meant was in the absence of assigning value to the key _val: (note the change with comments)
      use strict; use warnings; use Data::Dumper qw( Dumper ); sub samtregar { my $p = shift; my $val = pop; for my $item (@_) { $p->{$item} ||= {}; $p = $p->{$item}; } ### $p->{_val} = $val; } sub repellent { my $p = \shift; my $val = pop; $p = \$$p->{$_} for @_; ### $$p->{_val} = $val; } { samtregar(my $samtregar={}, qw( a b c d ), 'foo'); repellent(my $repellent, qw( a b c d ), 'foo'); { local $Data::Dumper::Useqq = 1; local $Data::Dumper::Terse = 1; local $Data::Dumper::Indent = 0; print("samtregar: ", Dumper($samtregar), "\n"); print("repellent: ", Dumper($repellent), "\n"); } } __END__ samtregar: {"a" => {"b" => {"c" => {"d" => {}}}}} repellent: {"a" => {"b" => {"c" => {"d" => undef}}}}

      while the nested hashes are being built, it doesn't leave an empty {} around. This behavior could be desirable.

      I didn't mean to say that mine doesn't vivify. It's almost the same, just subtly different as shown above.

      Hmmm ... as for the fetchers, shouldn't it be more consistent with:
      use strict; use warnings; use Data::Dumper qw( Dumper ); sub samtregar_fetcher { my $p = shift; for my $item (@_) { ### last if !$p->{$item}; $p->{$item} ||= {}; $p = $p->{$item}; } return $p->{_val} } sub repellent_fetcher { my $p = \shift; ### my $val = pop; $p = \$$p->{$_} for @_; return $$p->{_val}; } { samtregar_fetcher(my $samtregar={}, qw( a b c d )); repellent_fetcher(my $repellent, qw( a b c d )); { local $Data::Dumper::Useqq = 1; local $Data::Dumper::Terse = 1; local $Data::Dumper::Indent = 0; print("samtregar: ", Dumper($samtregar), "\n"); print("repellent: ", Dumper($repellent), "\n"); } } __END__ samtregar: {"a" => {"b" => {"c" => {"d" => {}}}}} repellent: {"a" => {"b" => {"c" => {"d" => {}}}}}

        I disagree. Why would fetching add to the data structure.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://747354]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (5)
As of 2024-03-29 11:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found