Question

I'm looking for help understanding why json_decode returns a scalar instead of a hash. I'm still learning perl and a description or some reference lit. would be great.

So the questions: Why does json_decode return a scalar? (or is it not a scalar) Is there a better way for me to work with the data?

Here is my code:

use strict;
use warnings;
use JSON qw(decode_json);
use LWP::UserAgent;

my $url = "http://api.bf4stats.com/api/playerInfo?plat=xbox&name=Ttylz00&output=json";

my $ua = LWP::UserAgent->new;
my $data = $ua->get($url);
my $json;
if($data->is_success){
    $json = decode_json($data->decoded_content);
}

&sData($json);

sub sData {
    my $data = $_[0];
    my $kdr = int($data->{stats}->{extra}->{kdr}*100)/100;
    printf "\nName: %s\nRank: %s, %s\nKDR: %s\n", $data->{player}->{name}, 
        $data->{player}->{rank}->{nr}, $data->{player}->{rank}->{name}, 
        $kdr;
}
Was it helpful?

Solution

In Perl, a function can only really return a scalar or a list.

Since hashes can be initialized or assigned from lists (e.g. %foo = (a => 1, b => 2)), I guess you're asking why json_decode returns something like { a => 1, b => 2 } (a reference to an anonymous hash) rather than (a => 1, b => 2) (a list that can be copied into a hash).

I can think of a few good reasons for this:

  • in Perl, an array or hash always contains scalars. So in something like { "a": { "b": 3 } }, the { "b": 3 } part has to be a scalar; and for consistency, it makes sense for the whole thing to be a scalar in the same way.
  • if the hash is quite large (many keys at top-level), it's pointless and expensive to iterate over all the elements to convert it into a list, and then build a new hash from that list.
  • in JSON, the top-level element can be either an object (= Perl hash) or an array (= Perl array). If json_decode returned a list in the former case, it's not clear what it would return in the latter case. After decoding the JSON string, how could you examine the result to know what to do with it? (And it wouldn't be safe to write %foo = json_decode(...) unless you already knew that you had a hash.) So json_decode's behavior works better for any general-purpose library code that has to use it without already knowing very much about the data it's working with.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top