Por que json_decode retorna um escalar?
Pergunta
Estou procurando ajuda para entender por que json_decode retorna um escalar em vez de um hash.Ainda estou aprendendo perl e uma descrição ou alguma referência acesa.seria ótimo.
Então as perguntas:Por que json_decode retorna um escalar?(ou não é escalar) Existe uma maneira melhor de trabalhar com os dados?
Aqui está o meu código:
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;
}
Solução
Em Perl, uma função só pode realmente retornar um escalar ou uma lista.
Como os hashes podem ser inicializados ou atribuídos a partir de listas (por exemplo, %foo = (a => 1, b => 2)
), acho que você está perguntando por que json_decode
retorna algo como { a => 1, b => 2 }
(uma referência a um hash anônimo) em vez de (a => 1, b => 2)
(uma lista que pode ser copiada em um hash).
Posso pensar em algumas boas razões para isso:
- em Perl, um array ou hash sempre contém escalares.Então, em algo como
{ "a": { "b": 3 } }
, o{ "b": 3 }
papel tem ser um escalar;e para consistência, faz sentido que tudo seja escalar da mesma maneira. - se o hash for muito grande (muitas chaves no nível superior), será inútil e caro iterar todos os elementos para convertê-lo em uma lista e, em seguida, criar um novo hash a partir dessa lista.
- em JSON, o elemento de nível superior pode ser um objeto (= hash Perl) ou um array (= array Perl).Se
json_decode
retornou uma lista no primeiro caso, não está claro o que retornaria no último caso.Após decodificar a string JSON, como você poderia examinar o resultado para saber o que fazer com ele?(E não seria seguro escrever%foo = json_decode(...)
a menos que você já soubesse que tinha um hash.) Entãojson_decode
O comportamento de funciona melhor para qualquer código de biblioteca de uso geral que precise usá-lo sem já saber muito sobre os dados com os quais está trabalhando.