http://qs1969.pair.com?node_id=431435


in reply to Frontier::Client mystery result string hash

Notice the square brackets around the curly ones. You have a reference to an array, not a reference to hash. The first (and only) element of the array is a reference to a hash, so:

print($result->[0]{'city'}, "\n");

or

foreach $record (@$result) { foreach $field (keys %$record) { printf("%s: %s\n", $field, $record->{$field}, ); } print("\n"); }

Replies are listed 'Best First'.
Re: Frontier::Client mystery result string hash
by brycen (Monk) on Feb 16, 2005 at 05:25 UTC
    Yup, you got it. I had been unable to create a matching data structure prior to your hint. This works:
    print "Print city: $result->[0]{'city'}\n";
    But I decided the following looked "cleaner". It makes me cringe, but here it is:
    my %hash = %{$result->[0]}; # copy result to new hash ... print "Print city: $hash{'city'}\n";
    I still can't quite figure out why Frontier::Client put this result in such a pointlessly nested data structure...
      Why would this be cleaner? You've got a reference to an array, containing a hash, meaning it only exists 1 time in your memory.
      Now you're dereferencing it into another hash, resulting in being twice in the memory. Do this with larger hashes over and over, and the memory usage becomes bigger and bigger.
      Print city: $result->[0]{'city'}\n"; is a verry legitimate way to write the results, i'd like the iterative way even more, in $result->[1] may be another hash, so i'd use ikegami's approach:
      foreach $record ( @{$result} ) { foreach $field (keys %$record) { printf("%s: %s\n", $field, $record->{$field}, ); } print("\n"); }

      This doesn't create a copy, just an alias:

      local %hash; *hash = $result->[0]; ... print "Print city: $hash{'city'}\n";
      I still can't quite figure out why Frontier::Client put this result in such a pointlessly nested data structure...

      Could it possibly return more than one result? Or maybe it's just extending a generic module that returns the data in that fashion.

        Tricky! Even the camel book harly touches on the * operator, relegating it to 'supported in C' in the index... I settled on the decidedly untricky:
        $geocode = $result->[0]; print "Match: lat=$geocode->{'lat'} long=$geocode->{'long'}\n";
      I still can't quite figure out why Frontier::Client put this result in such a pointlessly nested data structure...

      Because it's not pointless. The XML-RPC protocol allows for arrays of hashes. This means that the outer array is useful. It's just not useful in your situation.

      Being right, does not endow the right to be rude; politeness costs nothing.
      Being unknowing, is not the same as being stupid.
      Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
      Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.