http://qs321.pair.com?node_id=872769


in reply to Building data structures from CGI params

You mean you want to fetch the parameter list as a hash? It's right in the CGI documentation.

Update Ah - now I see, you want to do some "structured" parameters. No, I'm not aware of something like that, but if you go for dots as delimiters, it's fairly easy to write yourself:

my %params = $q->Vars; my @keys = keys %params; for my $k (sort @keys) { if (/[.]/) { my $v = delete $params{ $k }; my $level = \%params; my @items = split /[.]/, $k; my $key = pop @items; for (@items) { $level->{ $_ } ||= {}; $level = $level->{ $_ }; }; $level->{ $key } = $v; }; };

Replies are listed 'Best First'.
Re^2: Building data structures from CGI params
by fullermd (Priest) on Nov 21, 2010 at 09:53 UTC

    No, for the example HTML I had:

    <input type="text" name="foo{bar}" value="barval"> <input type="text" name="foo{baz}" value="bazval">

    that would yield me

    $params = { "foo{bar}" => "barval", "foo{baz}" => "bazval" }

    I want

    $params = { foo => { bar => "barval", baz => "bazval", } }
    EDIT

    Pshaw, you update'd while I was typing :)

    Yes, it's not (in the simple case) that hard to code up. Handling params like foo{bar}[6]{baz}[2] gets a little more involved though. It's just complex enough that I'm confident I'll either make a mistake somewhere, or wind up with code with somewhat unpleasant performance characteristics in extremis. So I'd hoped (and it seems such an obvious thing to want that I'd expected) there was an existing module I could mooch off^W^Wutilize...

Re^2: Building data structures from CGI params
by fullermd (Priest) on Nov 29, 2010 at 04:10 UTC
    Ah - now I see, you want to do some "structured" parameters. No, I'm not aware of something like that, but if you go for dots as delimiters, [...]

    Unfortunately (fortunately ;) this is perl, so we have to have multiple delimiters to be able to support both hashes and arrays. That makes things a little more complicated (not to mention that pesky error checking).

    Thanks to you (and Anonymous below) for the code drops. I wasn't really looking for "help me write this code" so much as "help me find the module that surely already exists to do it", but I'm continually impressed at the willingness of the Monks to go that extra mile.

    Sadly, none of us were successful at finding the existing module. I'm still shocked by that. Left me no choice but to go solve it.

    So I did, and the next time someone asks, we can tell them CGI::Struct.

    Annoyingly, I just got a mail about a test failure on 5.6.2. At a glance, it looks like it's just a problem 5.6 has with the test, not an actual code issue. Hrumph. Now I need to decide whether I want to fight through a 5.6 install somewhere to fix it...

      You forgot how CGI::Vars works, https://metacpan.org/module/CGI::Struct#Auto-arrays doesn't account for it

      #!/usr/bin/perl -- use strict; use warnings; use Data::Dump; use CGI; use CGI::Struct; my $q = CGI->new('row[]=row;row[]=row;row[]=row;row[]=your boat'); my %qVars = $q->Vars; my @errors; my $struct = build_cgi_struct \%qVars, \@errors; dd $q, \%qVars, $struct, \@errors; ### WORKAROUND for stupid Vars (must've written this line 100 times) %qVars = map { $_ => [ $q->param($_) ] } $q->param; dd \%qVars; $struct = build_cgi_struct \%qVars, \@errors; dd $struct, \@errors; __END__ ( bless({ ".charset" => "ISO-8859-1", ".fieldnames" => {}, ".iterator" => 2, ".parameters" => ["row[]"], "escape" => 1, "param" => { "row[]" => ["row", "row", "row", "your boat"] +}, "use_tempfile" => 1, }, "CGI"), { "row[]" => "row\0row\0row\0your boat" }, { row => ["row\0row\0row\0your boat"] }, [], ) { "row[]" => ["row", "row", "row", "your boat"] } ({ row => ["row", "row", "row", "your boat"] }, [])

        I'm not sure what you mean. { row => ["row", "row", "row", "your boat"] } looks like the "right" answer to me...

        What were you expecting?