Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

How to loop through Plack::Request body_parameters ?

by knox (Sexton)
on Feb 12, 2020 at 01:38 UTC ( #11112825=perlquestion: print w/replies, xml ) Need Help??

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

Still learning how to do perl with plack. I have a simple app to post check boxes and other form elements. I would like to loop through check box name and value and place them in a new hash. These are obtained through a post request in Plack::Request body_parameters. Where am stuck is how to loop through the Plack::Request body_parameters. Dumper body_parameters as follows:

$VAR1 = bless( { 'c_xcode' => 'J23-H0P', 'c_ycode' => 'G12-Y4T', 'c_zcode' => 'Q87-S7B', 's_xlist' => 'T66-Y9A', 's_ylist' => 'A43-P9W', 's_zlist' => 'T71-K2L' }, 'Hash::MultiValue' );
What I would like is to convert body_parameters into a hash like this:
%form_hash = ( 'c_xcode' => 'J23-H0P', 'c_ycode' => 'G12-Y4T', 'c_zcode' => 'Q87-S7B', 's_xlist' => 'T66-Y9A', 's_ylist' => 'A43-P9W', 's_zlist' => 'T71-K2L' );

What is the best way to do this? Here's what I've tried, which I got close - it prints my desired hash to dumper, but I can't pass the \%form_hash to the foreach loop below:

my $form = $posted->body_parameters; my @k = keys %$form; my @v = values %$form; @form_hash{@k} = @v; # Dumper ( \%form_hash) works, but can't pass this to foreach; # "Experimental keys on scalar is now forbidden" when trying on # foreach my $key (sort(keys( \%form_hash ))) below.
Here is the complete snippet
#!/usr/bin/perl use strict 'refs'; use Plack::Request; use Data::Dumper; my $app = sub { my $env = shift; my $form = Plack::Request->new($env); print Dumper ( $form->body_parameters ) ; #how to convert $form->body_parameters to new %form_hash? my %form_hash; my %cb_hash; foreach my $key (sort(keys( %form_hash ))) { if ( substr($key,0,2) eq "c_" ){ my $cb_key = $key; my $cb_val = $form_hash{$key}; $cb_hash{$cb_key} = $cb_val; } } };

Replies are listed 'Best First'.
Re: How to loop through Plack::Request body_parameters ?
by Your Mother (Bishop) on Feb 12, 2020 at 03:47 UTC

    Anonymonk covered Hash::MultiValue. All you need–

    my $params = $form->body_parameters->as_hashref; # or my %params = %{$form->body_parameters};

    Some tips. use strict 'refs' is code smell. It’s half way to not using strict at all which is, for any code longer than you can easily understand in a glace, like swimming while carrying a brick.

    I was surprised to see that the following is apparently reliable and even approximately shown in the docs for keys. I was surprised because hash keys are “unordered” so this looks funky but the values and keys are “unordered” in the same way so… Anyway, it seems a bit too clever to me and might lead you to believe you can rely on order between different hashes.

    my @k = keys %$form; my @v = values %$form; @form_hash{@k} = @v;

    I am absolutely not trying to dissuade you from learning and experimenting. That said, Plack is not meant for what it seems like you’re doing. It’s a low level toolkit, not a web application framework. Keep playing around. It’s fun. Consider picking up Mojolicious or another webapp framework if you’re serious about making code for anyone but yourself. There are many parts that are either done already or make everything much easier. The suggestion about Plack::App::WrapCGI may also be cromulent. Your old FCGI code could likely just be wrapped up. The CGI code has to be pretty clean but the error feedback is quite good, though nothing you’d ever want to expose to users, so…

      It's not just approximately shown; the keys documentation explicitly says that (so long as it's not modified) they will return the same order for the same hash (emphasis mine):

      Hash entries are returned in an apparently random order. The actual random order is specific to a given hash; the exact same series of operations on two hashes may result in a different order for each hash. Any insertion into the hash may change the order, as will any deletion, with the exception that the most recent key returned by "each" or "keys" may be deleted without changing the order. So long as a given hash is unmodified you may rely on "keys", "values" and "each" to repeatedly return the same order as each other.

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

        I did mention that the doc for keys says this. :P

        thanks! Not sure if my implementation was the best in this case, but its good to know this.
      use strict 'refs' is code smell.

      Definitely. knox: If you're already working on something as relatively modern as Plack, then you should definitely also use the modern practices of Use strict and warnings. There's a reason e.g. Mojolicious::Lite turns them on by default.

        thank you.

        It's something I've picked up from an older tutorial and something I will change. It was just a rookie's assumption that if it had any sort of 'use strict' was ok, after testing it, i've got a lot of little things to fix. I appreciate the heads up. (the Ovid article linked to the strict warnings article is also good).

      thanks!

      I am absolutely not trying to dissuade you from learning and experimenting.

      I appreciate that sentiment - I have a wee project that has gone from cgi to fcgi and now plack. It's just a hobbie project for me to learn Perl, nothing to be released in wild. I realise there are faster implementations to get through the gate, but each step has had certain and 'ah-ha!' moments for me, which adds to the richness of the language and also how the web protocols work. I've already had a look at some the Mojolicious documentation, so that is on the horizon soon.

      Also thanks for the other suggestions (eg strict and keys).

Re: How to loop through Plack::Request body_parameters ?
by Anonymous Monk on Feb 12, 2020 at 02:56 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11112825]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2020-05-25 15:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    If programming languages were movie genres, Perl would be:















    Results (146 votes). Check out past polls.

    Notices?