Estou aprendendo Perl. Eu sou capaz de iterar sobre uma coleção JSON usando uma estrutura de dados de hash Perl como esta usando dados de amostra. No entanto, os dados reais contêm alguns elementos que estão causando o erro Not a HASH reference
ou Can't use string ("...") as a HASH ref while "strict refs" in use
.
Aqui está um exemplo simplificado de dados problemáticos que estão me causando problemas:
{
"0y7vfr1234": {
"username": "[email protected]",
"password": "some-random-password123",
"uri": "ww1.example.com",
"index": 14
},
"v2rbz1568": {
"username": "[email protected]",
"password": "some-random-password125",
"uri": "ww3.example.com",
"index": 29
},
"active": "0y7vfr1234",
"0zjk1156": {
"username": "[email protected]",
"password": "some-random-password124",
"uri": "ww2.example.com",
"index": 38
},
"logging": {
"active": true
}
}
Estou preocupado apenas com os elementos de dados que têm uma extensão uri
. Eu quero pular os outros. Como eu faria isso?
Depois de tentar dezenas de coisas que não funcionaram (e só levaram a erros novos ou diferentes), aqui está como eu finalmente contornei os erros. No entanto, suponho que há uma maneira muito melhor de fazer isso do que usar o ref()
.
#!/usr/bin/perl
use JSON;
use utf8;
use Data::Dumper;
use strict; use warnings;
my $data = '{
"0y7vfr1234": {
"username": "[email protected]",
"password": "some-random-password123",
"uri": "ww1.example.com",
"index": 14
},
"v2rbz1568": {
"username": "[email protected]",
"password": "some-random-password125",
"uri": "ww3.example.com",
"index": 29
},
"active": "0y7vfr1234",
"0zjk1156": {
"username": "[email protected]",
"password": "some-random-password124",
"uri": "ww2.example.com",
"index": 38
},
"logging": {
"active": true
}
}';
my $json = decode_json($data);
foreach my $key (keys %$json) {
if ( ref( $json->{$key} ) !~ m/HASH/ ) {
print "[" . ref( $json->{$key} ) . "]: skipping\n";
next;
}
if ( ! exists $json->{$key}->{uri} ) {
print "Not a server. It's type is: [" . ref($json->{$key}) . "]\n";
print "Without curly braces: $json->$key\n";
print Dumper($json->{$key});
print "With curly braces: $json->{$key}\n";
next;
}
print "checking $json->{$key}->{uri}\n";
# do some other stuff
}
O código funciona mais ou menos como está, mas não estou feliz com ele... ou com minha compreensão dele.
Minhas perguntas são:
- Qual é a maneira correta de iterar dados "mistos", como meu JSON, sem encontrar erros?
- Qual é uma boa maneira de exibir algumas informações sobre os elementos que eu pulo? Tentei várias coisas no código (Data Dumper, impressão sem chaves, etc.) e nenhuma delas é satisfatória. Existe uma maneira melhor de mostrar informações sobre o que foi ignorado (sem causar um erro, é claro)?
- Por que o código acima
$json->{$key}->{uri}
também funciona sem a seta assim:$json->{$key}{uri}
?
Estou usando perl 5, versão 30 no Linux.