darkphorm has asked for the wisdom of the Perl Monks concerning the following question:

I have a function similar to the following:
sub sub_pick_group_seg { my ($str) = @_; my $working=$str; my @groups; while ( $working =~ s/<\@=([\w\d\_\ ]+)>(.*?)<\/\@=\1>/<\@=\1>/gs ) { my $name=$1; my $newvalue=$2; if ($name ne "") { my $gcount=@groups; my @subgroup; my $newvalue; ($newvalue, @subgroup)=sub_pick_group_seg ($newvalue); $groups[$gcount]{name}=$name; $groups[$gcount]{value}=$newvalue; my $subcount=@subgroup; if ( $subcount > 0 ) { $groups[$gcount]{sub}=@subgroup; } } } return ($working, @groups); }
Where all works, except at line: $groups[$gcount]{sub}=@subgroup;

There, the function should have called itself previously, and if it got values, tack them onto this hash/array. I haven't really figured out references, so I'm fairly sure this is where I'm going wrong. How would I make it so that $groups[$gcount]{sub} gets values, par example so I can pull:
$groups[0]{sub}[0]{name}
or even
$groups[0]{sub}[0]{sub}[2]{name}
it should keep going in this way. update: Worked with $groups[$gcount]{sub}=@subgroup;

However, now when pulling values: I get an error with this code:
my $arr= @group[$indx]; print "---*--- " . join(",", keys(%$arr) ) . "<br>\n"; print "--+ " . $$arr{name} . "<br>\n";


Which is odd since the output is:
---*--- value,name<br> Bad index while coercing array into hash at ./mod/subst.cgi line 65.

If there is a key called "name" (as indicated by the first return line), should $$arr{name} be a valid call?

Replies are listed 'Best First'.
Re: Recursive function adds data to a hash/array
by kvale (Monsignor) on Mar 10, 2004 at 19:04 UTC
    If you want to attach an array to a hash element, try
    $groups[$gcount]{sub}=[@subgroup]; my $first_data = $groups[0]{sub}[0];
    The  [] creates an anonmyous array that is attached as a reference to  $groups[$gcount]{sub}.

    Update: My gues is that the code is parsing nested tags. The sub recursively calls itself on the string $newvalue found between a pair of tags. When there is no more text to parse, the recursion ends. While parsing, the intent is to build a tree of data enclosed in the tags. Thus the question on nested data structures.

    -Mark

      You've hit it on the head. The code parses tags, some of which can be nested, in order to insert data elements into the tags.

      When there are no more nested elements, there is no more recursion.

      This part works now... but I'm now trying to figure out how to recursively pull back out
      $groups[$indx]{sub}[$subindex]...
Re: Recursive function adds data to a hash/array
by Happy-the-monk (Canon) on Mar 10, 2004 at 19:00 UTC

    darkphorm writes: There, the function should have called itself previously, and if it got values, tack them onto this hash/array.

    I am puzzled as to how you think the function would be calling itself. I can't see it in the code. If you want the function to call it self, why don't you just call it?

    Obviously it might be a bad idea to call a function recursively if there is no end to the recursion... but that's not your question, or is it?

    Where do you think references should come in?

    Sören

      I am puzzled as to how you think the function would be calling itself. I can't see it in the code.
      ($newvalue, @subgroup)=sub_pick_group_seg ($newvalue);
      So while it is indeed calling itself, it would be nice if darkphorm explained in plain english what was trying to be accomplished. Better yet, included a small example of input and desired output. I can't make heads or tails of it.
      L~R
        The input is an HTML file:

        <HTML> <HEAD> <TITLE><$=TITLE></TITLE> </HEAD> <BODY> This is a test of variable substition.<br> <br> Date=<$=DATE><br> <br> <table border=1> <tr> <th>firstname</th><th>lastname</th><th>Accounts</th> <tr> <@=USERDATA> <tr> <td><$=FIRSTNAME></td> <td><$=LASTNAME></td> <td> <table> <tr> <th>Account ID</th> <th>type</th> <th>Balance</th> </tr> <@=ACCOUNTDATA> <tr> <td><$=ACCID></td> <td><$=ACCTYPE></td> <td><$=ACCBALANCE></td> </tr> </@=ACCOUNTDATA> </table> </td> <tr> </@=USERDATA> </table> </BODY>


        The concept is to make the manipulation of the custom tags easy, so that the HTML-devs can do their thing with a page, and data can be easily inserted with hash variables.

        thank you Limbic~Region, I must have been blind not to see that line... hmm.

        Cheers, Sören