in reply to Inheritance in Hash

How do you like the folowing?

use strict; use warnings; sub get { my $ref = shift(@_); my $key = shift(@_); my $val; for (;;) { last unless UNIVERSAL::isa($ref, 'HASH'); $val = $ref->{$key} if exists $ref->{$key}; last unless @_; my $branch = shift(@_); $ref = $ref->{$branch}; } return $val; } my $data = { Colour => 'blue', Entries => { Flowers => { Dahlia => { Smell => 'nice' }, Rose => { Colour => 'red' }, }, }, }; print get($data, 'Colour', qw( Entries Flowers Rose )), $/, # red get($data, 'Colour', qw( Entries Flowers Dahlia )), $/; # blue

If $data was blessed to the package which contained get, you could improve the syntax a bit:

print $data->get('Colour', qw( Entries Flowers Rose )), $/, # red $data->get('Colour', qw( Entries Flowers Dahlia )), $/; # blue

Replies are listed 'Best First'.
Re^2: Inheritance in Hash
by ikegami (Patriarch) on Apr 21, 2005 at 03:54 UTC

    Here's a version with a better syntax:

    # Using "tie". use Tie::Hash::Inheriting (); { tie(my %data, 'Tie::Hash::Inheriting'); %data = ( Colour => 'blue', Entries => { Flowers => { Dahlia => { Smell => 'nice' }, Rose => { Colour => 'red' }, }, }, ); print $data{'Entries'}{'Flowers'}{'Rose' }{'Colour'}, $/, # red $data{'Entries'}{'Flowers'}{'Dahlia'}{'Colour'}, $/; # blue untie(%data); # Free mem. %data going out of scope is not enough. }

    or

    # Using objects. use Hash::Inherting (); { my $data = Hash::Inheriting->new(); %$data = ( Colour => 'blue', Entries => { Flowers => { Dahlia => { Smell => 'nice' }, Rose => { Colour => 'red' }, }, }, ); print $data->{'Entries'}{'Flowers'}{'Rose' }{'Colour'}, $/, # red $data->{'Entries'}{'Flowers'}{'Dahlia'}{'Colour'}, $/; # blue }

    Tie/Hash/Inheriting.pm

    Hash/Inheriting.pm

      bah, there are still memory leaks, I think.

      $data{'moo'}{'test'} = { a => 1, b => 2 }; # The following line doesn't free the tied hash # containing a => 1, b => 2 until %data is untied. $data{'moo'}{'test'} = 'foo';