in reply to Best Hash Practices?

> All ideas are welcome...

ok ... what about this?

use strict; use warnings; sub xdefined { my $ref=shift; my $type; while ( my $key=shift) { $type= ref($ref); if ( $type eq "HASH" ) { return unless defined $ref->{$key}; $ref=$ref->{$key} } elsif ( $type eq "ARRAY" ) { return unless defined $ref->[$key]; $ref=$ref->[$key] } else # no reference { return }; } return defined $ref; } my $h->{a}->[2]->{c}=0; $\="\n"; $,=":"; print 5, xdefined($h,"a",2,"c",4,"e"); print 4, xdefined($h,"a",2,"c",4); print 3, xdefined($h,"a",2,"c"); print 2, xdefined($h,"a",2); print 1, xdefined($h,"a"); print 0, xdefined($h);
-->
5 4 3:1 2:1 1:1 0:1

Using prototypes like (\[%@]@) can further "beautify" the interface! 8)

Cheers Rolf

Replies are listed 'Best First'.
Re^2: Best Hash Practices?
by DamianKaelGreen (Acolyte) on Oct 12, 2009 at 17:51 UTC

    Yes, this is the direction I was headed with this too... It would be nicer though if the input to the function was just the autovivified list of keys though, so we could maintain a more usual appearance, like:

    print 6, isDefined($h{"a"}{2}{c}{4});

    This is a kind of standard function that I think should be developed more thoroughly for everyone to use regularly; Either that, or the fundamentals of the way a multidimensional hash is handled should possibly be re-evaluated to recognize when something is being created vs when it's being tested...

      Hi

      I know what you mean but the syntax you're proposing is not feasible, since it's the arrow operator which is autovivifying!

      isDefined($h{"a"}->{2}->{c}->{4});

      So when isDefined comes into action it's already to late!

      Anyway one can easily extend the syntax of my approach to make it "smoother"!

      xdefined(%h => qw/a 2 c 4/)

      or

      xdefined(%h => "a",2,"c",4)

      But IMHO (within the boundaries of perl) the syntactically "prettiest" way to go would be to use a tied copy of your hash, like this you may be able to write

      novivi(%h)->{a}{2}{c}{4}

      %h2=novivi(%h) should be an empty hash with a hash-tie which mirrors safely the structure of %h.

      Such that $h2{a} is only be defined iff $h{a} is defined and all the automatically vivified structures in $h2{a}{2}{c}{4} are automatically tied hashes bound to the corresponding structures in %h.

      Well ... I think this is feasible, BUT should come with a significant performance penalty compared to my first approach, since ties are expensive.

      Cheers Rolf