convert string to hash of hash?

Discussion in 'Perl Misc' started by dt, Mar 1, 2007.

  1. dt

    dt Guest

    I have a data set such as this:

    $ref{"a"}{"b"}[0]{"c"}

    any way to take a string such as:

    "a:b:[0]:c" and get the value stored in $ref{"a"}{"b"}[0]{"c"}?

    does using Data::Dumper help?

    I want to be able to put a string in a template file which gets the
    value from the datastructure,
     
    dt, Mar 1, 2007
    #1
    1. Advertising

  2. dt

    ~greg Guest

    "dt" > wrote...
    >I have a data set such as this:
    >
    > $ref{"a"}{"b"}[0]{"c"}
    >
    > any way to take a string such as:
    >
    > "a:b:[0]:c" and get the value stored in $ref{"a"}{"b"}[0]{"c"}?
    >
    > does using Data::Dumper help?


    Yes! Always does!
    ~~

    When I was trying understand perl references I came up with
    the following subroutine: "Node()".

    It is essentially the same idea that Jim Gibson mentioned,
    but much more general.

    The syntax for its use is:

    ${ Node( \$structure, $index1, $index2,...) }

    This can be both assigned to, and read from, just as is!

    The indices are either text or integers.
    (--taken to be integral iff =~ /^\d+$/)

    The first argument to Node() is a pointer to a pointer to a structure.
    The $structure can be initially undefined.

    I don't see that any special error-checking is required.
    However there is one cavat.

    If you write to (or even try to read from)
    incompatible signatures, then you loose information.

    "signature" meaning the specific sequence of the argument types,
    - integers (for arrays) and text ( for hashes).

    If, in the same argument place, you once use a text
    index, but then later use an integer, it's not an error.
    But the whole hash branch at that point gets lost.

    An example of this is included below (--the "busted").

    ~greg

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    use strict;
    use warnings;
    use Data::Dump qw(dump);
    $|=1;

    sub Node
    {
    my $p = shift;
    foreach my $i (@_)
    {
    if($i =~ /^\d+$/)
    {
    $$p=[] if ref($$p) ne 'ARRAY';
    $$p->[$i] = undef if ! exists $$p->[$i];
    $p = \$$p->[$i];
    }
    else
    {
    $$p={} if ref($$p) ne 'HASH';
    $$p->{$i}=undef if ! exists $$p->{$i};
    $p = \$$p->{$i};
    }
    }
    return $p;
    }


    my $Struct;

    ${Node( \$Struct, (split /\W+/, "a:b:[0]:c") ) } = 'this is ';
    ${Node(\$Struct, 'a','b',3,'d','e') } = 'a test';

    print ${Node(\$Struct,'a','b',0,'c')};
    print ${Node(\$Struct,'a','b',3,'d','e')};

    print "\n";
    dump($Struct);


    print "~~~~~~~~~~~~~~~~~~~~~\n";
    # An example of loosing information
    # by assigning to a different signature:
    # (--the 'b' and the '3' have been interchanged)

    ${Node(\$Struct, 'a',3,'b','d','e') } = 'busted!';

    #print ${Node(\$Struct,'a','b',0,'c')}; # error (undef)
    #print ${Node(\$Struct,'a','b',3,'d','e')}; # error (undef)

    print ${Node(\$Struct, 'a',3,'b','d','e') };
    print "\n";
    dump($Struct);

    __END__

    PRINTS:...

    this is a test
    {
    a => {
    b => [{ c => "this is " }, undef, undef, { d => { e => "a test" } }],
    },
    }
    ~~~~~~~~~~~~~~~~~~~~~
    busted!
    {
    a => [undef, undef, undef, { b => { d => { e => "busted!" } } }],
    }
     
    ~greg, Mar 2, 2007
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. rp
    Replies:
    1
    Views:
    562
    red floyd
    Nov 10, 2011
  2. Nick Snels

    Convert String to Hash

    Nick Snels, Mar 9, 2006, in forum: Ruby
    Replies:
    7
    Views:
    222
    Nick Snels
    Mar 9, 2006
  3. Fransiscus Xaverius
    Replies:
    0
    Views:
    96
    Fransiscus Xaverius
    Dec 13, 2007
  4. Srijayanth Sridhar
    Replies:
    19
    Views:
    655
    David A. Black
    Jul 2, 2008
  5. Replies:
    2
    Views:
    192
    John Bokma
    Aug 30, 2013
Loading...

Share This Page