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

The below code fails as it errors out saying "odd number of results in anonymous hash". Now I don't see why any of this is being read as an anony hash, so I come to you monks in hope of englightenment on what the issue is and what I need to do to get around it.
#assuming $form_string is either form_name or form_number # assuming $param_string are key/values separated with => $mech->submit_form( $form_string => $d, fields => { $param_string });

Replies are listed 'Best First'.
Re: passing a variable as a string
by tirwhan (Abbot) on Feb 28, 2006 at 17:11 UTC

    Curly braces {} are used to create a reference to an anonymous hash, so the construct

    fields => { $param_string }

    Assigns an anonymous hash reference as the value to the hash key "fields". And since there is only one element ($param_string) inside the braces (instead of one or many key=>value pairs) you get an error message.


    All dogma is stupid.
      What would the fix be then?

      I know I surely can't remove the { and } around that block to make it not a hash.

      Thanks!

Re: passing a variable as a string
by davido (Cardinal) on Feb 28, 2006 at 17:15 UTC

    Here's a brief analysis:

    $mech->submit_form( # invoke the submit_form() object method. $form_string => $d, # Anything to the left of a # => is treated as like it's 'single quoted' # That means variables are not interpolated. # This is a possible bug in your script, # but not the one you're asking about. # *** Next comes the bug you're asking about. fields => { # The curly bracket begins an # anonymous hash. $param_string # This is a single scalar value } # You've completed the creation of the anonymous hash, but # you created it with one key (the contents of $param_string) # and no associated value. So you get an error message. );

    If you want $param_string to represent a bunch of key/value pairs, you should first split it on its delimiter. After reading the comment in your code I assume you mean that the string is key/value delimited with =>, and each pair delimited with something else like maybe comma (,). If that's correct, this ought to do what you want:

    $mech->submit_form( $form_string, $d, fields => { split( /=>\s+|,\s+/, $param_string ) } );

    Of course you'll get into trouble quickly if it turns out that you have embedded commas within quoted text, and that sort of thing. If that's the case, you'll probably want to parse $param_string with a more robust tool.


    Dave

      # Anything to the left of a # => is treated as like it's 'single quoted' # That means variables are not interpolated.

      Variables are interpolated on the left of a =>. E.g.

      perl -MData::Dumper -le '$foo = "blah"; %a = ( $foo => 42 ); print Dumper \%a' $VAR1 = { 'blah' => 42 };

      Hooray for DWIMery.

      Update: Fixed formatting

        Damn you for being right! (just kidding)

        And here's the relevant quote from perlop:

        The => operator is a synonym for the comma, but forces any word (consisting entirely of word characters) to its left to be interpreted as a string (as of 5.001). This includes words that might otherwise be considered a constant or function call.

        I won't be modifying my previous post; let the record show the error and its clarification. I'm sure someone will find it useful.

        As for my assessment as to why his anonymous hash has only one element, and what might be done to correct the situation, my advice is still applicable.


        Dave