I won't debate the logic of what your doing. I did something along the same lines for an embedded language where I didn't care about "strictness" of variable references. Though you may want to reconsider.

The code below expects that keys components m/\.\d+\./ are array indexes. Letter keys are hash keys. Beware that perl arrays are not sparse so a.1000000000.f might ruin your day so $MAX_ARRAY_INDEX sets an upper limit. Beware that if a.b.c is a hash and you then say a.b.1, this will happily discard that hash at a.b.c and created an array at a.b

This was written in haste and from memory so user beware, also your example would have to chance slightly. a.b.c values would have to become a.b.c.1,a.b.c.2 etc. or just assign at once getset_key(\%form,'a.b.c',\@values).

#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my %form = ( a=>5,); print Dumper (\%form); print get_key(\%form,'a.b.c'),"\n" ; # Doesn't vivify print Dumper (\%form); getset_key(\%form,'a.b.c', 55); # Set $form{a}{b}{c} to 55 print Dumper (\%form); getset_key(\%form,'a.a.c.d', "umkay"); #Set $form{a}{a}{c}{d} to umkay print Dumper (\%form); getset_key(\%form,'a.b.c.d', 15); #Set $form{a}{b}{c}{d} to 15, bye c= +55! print Dumper (\%form); getset_key(\%form,'a.b.1', 100); # Sets $form{a}{b}[1] = 100 print Dumper (\%form); getset_key(\%form,'a.b.11111111', 10); # Array too big, bails print Dumper (\%form); BEGIN { my $MAX_ARRAY_INDEX = 100; sub get_key { # Does not vivify non existant keys my $h = shift; my $k = shift; die "You need to pass a reference to get_key!" unless ref($h); die "No key specified!" unless defined $k; my @p = split(/\./,$k); die "An index is too big!: ".join(', ',@p) if grep { $_=~m/^\d+ +$/ && $_ > $MAX_ARRAY_INDEX} @p; my $v = get_avhv($h,@p); } sub getset_key { # Does vivify non existant keys my $h = shift; my $k = shift; my $v = shift; die "You need to pass a reference to get_key!" unless ref($h); die "No key specified!" unless defined $k; my @p = split(/\./,$k); die "An index is too big!: ".join(', ',@p) if grep { $_=~m/^\d+$ +/ and $_ > $MAX_ARRAY_INDEX} @p; vivify_avhv($h,@p,$v); } sub vivify_avhv { my $h = \shift; my $v = pop; local $_; while (@_){ if ($_[0]=~/^\d+$/){ $$h = [] unless UNIVERSAL::isa( $$h, "ARRAY" ); $h = \$$h->[shift ()]; }else{ $$h = { } unless UNIVERSAL::isa( $$h, "HASH" ); $h = \$$h->{shift()}; } } $$h = $v; return $h; } ################################################# sub get_avhv { my $h = \shift; local $_; while (@_){ if ($_[0]=~/^\d+$/){ return unless UNIVERSAL::isa( $$h, "ARRAY" ); return if $_[0] >= @{$$h} ; # Prevent autoviv $h = \$$h->[shift ()]; }else{ return unless UNIVERSAL::isa( $$h, "HASH" ); return if ! exists $$h->{$_[0]}; # Prevent autoviv $h = \$$h->{shift()}; } } return $$h; } }


-Lee

"To be civilized is to deny one's nature."

In reply to Re: Initializing Hashes of Hashes (of Hashes) by shotgunefx
in thread Initializing Hashes of Hashes (of Hashes) by bsb

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.