2015-06-10 2 views
2

Почему это не работает?Декодирование Hash от JSON-String в Perl

my $myHashEncoded = encode_json \%myHash; 
my %myHashDecoded = decode_json($myHashEncoded); 

Я получаю ошибку:

Reference found where even-sized list expected at ... 

Так что я изменил его:

my $myHashEncoded = encode_json \%myHash; 
my $myHashDecoded = decode_json($enableInputEncoded); 

Но тогда, очевидно, %myHash не то же самое, как $myHashDecoded.

Как восстановить правильный хэш из строки JSON?

+1

С какого модуля вы получаете 'encode_json' и' decode_json'? – Quentin

+0

Я включил использование JSON; – Linus

+0

Вы можете разыменовать хеш, 'my% myHashDecoded =% {decode_json ($ enableInputEncoded)};' –

ответ

5

Предполагая, что вы используете JSON.pm, the documentation says:

The opposite of encode_json: expects an UTF-8 (binary) string and tries to parse that as an UTF-8 encoded JSON text, returning the resulting reference.

Таким образом, вы получаете обратно то, что вы положили в Ты ставишь в hashref и вы получаете hashref назад..

Если вы хотите регулярного хэша, то вы просто разыменования его, как и любой другой hashref:

my $myHashRefDecoded = decode_json($myHashEncoded); 
my %myHashDecoded = %$myHashRefDecoded; 
+0

Спасибо за быструю перезагрузку. И жаль мое невежество относительно документации. – Linus

+0

Это действительно помогло мне понять некоторые аспекты Perl, которые (как новичок) не имели для меня большого смысла. Благодаря! – Kellen

2

Вы кодируете ссылку на хэш (encode_json \%myHash), что является правильным. Поэтому, когда вы декодируете строку JSON, вы получаете ссылку на хэш. Подготовьте сингл % к хеш-ссылке, чтобы разыскать его.

$myHashReferenceDecoded = decode_json($myHashReferenceEncoded); 
%myHashDecoded = %$myHashReferenceDecoded; 
1

JSON API соответствует. Если вы используете ссылку на хэш во время кодирования, вы также получаете хеш-ссылку при декодировании. Итак, если вы хотите сохранить результат в чистой хэш-переменной, вы должны разыменовать результат decode_json с %{ ... }.

Решение:

my $myHashEncoded = encode_json \%myHash; 
my %myHashDecoded = %{ decode_json($myHashEncoded) }; 

Обратите внимание, что разыменования хэша является дорогостоящей операцией. Вы действительно должны подумать, если в вашем коде использовать ссылку недостаточно.

1

На следующей строке, вы делаете две вещи: вы создаете ссылку на хэш (\), и кодировать результат (encode_json):

my $myHashEncoded = encode_json(\%myHash); 

Одна следующая строка, вы декодировать JSON (decode_json), но вы не отменяете ссылку.

my %myHashDecoded = decode_json($myHashEncoded); 

Реальная обратная операция будет включать в себя хеширование.

my %myHashDecoded = %{ decode_json($myHashEncoded) }; 

Но это ненужно делает (неглубокую) копию хеша. Возможно, вам стоит просто работать с ссылкой.

my $myHashDecoded = decode_json($myHashEncoded); 

Кстати, причина используется ссылка является то, что невозможно передать хеш к югу или возвращать хэш из суб. Можно передавать и возвращать только список скаляров.