#json #perl
#json #perl
Вопрос:
У меня проблема с преобразованием моих данных в json, и я не знаю почему.
Вот некоторый код, который работает:
#constructor
sub new {
my $class = shift;
my $Titel = shift;
my $Text = shift;
my $Time = localtime;
my $self = {};
$self->{text} = $Text;
$self->{create} = $Time;
$self->{edit} = $Time;
my $json = JSON::XS->new();
open WF, '>> $file' || die "Error : $!";
print WF $json->encode($self)."n";
close WF;
bless $self, $class;
}
Я создаю ‘object’ и сохраняю данные также в текстовом файле (через JSON).
У меня возникают проблемы, если я пытаюсь отредактировать некоторые данные:
sub edit {
my $self = shift;
my $Text = shift;
my $ID = shift;
my $Time = localtime;
my $json = JSON::XS->new();
$json->allow_blessed(1);
$self->{text} = $Text; #edit text
$self->{edit} = $Time; # edit date
open INPUT, '< $file' || die "Error : $!";
my @data = <INPUT>;
close(INPUT);
open WF, '> $file' || die "Error : $!";
for (my $Count=0; $Count<=$#data; $Count ){
chomp($data[$Count]);
if($Count == $ID){#if line of data found, who is going to be edited
print WF $json->encode($self)."n";
}else{
print WF $data[$Count]."n";
}
}
close WF;
}
Что я пытаюсь сделать, так это отредактировать всего одну строку в текстовом файле.. (если у вас есть идея получше, пожалуйста, покажите мне: D)
Я не вижу разницы между моей процедурой в коде, показанном первым, и этой….
он просто записывает «null» обратно в текстовый файл…
Есть идеи?
Комментарии:
1. Вам нужно использовать двойные кавычки вокруг вашего второго аргумента to
open
, поскольку имеющиеся у вас сейчас одинарные кавычки не будут интерполировать$file
переменную. Еще лучше использовать форму с тремя аргументамиopen INPUT, '<', $file
2. Моя проблема в том, что он записывает «null» обратно в строку —> print WF $ json-> encode($ self).» n»;<— я могу открыть файл и так далее (я отредактировал код .. неправильно. извините:D в моем исходном коде указан путь, а не ‘$ file’. не знал этого)
3. Вызывается ли «дополнительное редактирование» как метод? т.е. «$thing-> edit ()»?
4. да. я отладил его, и $ self является правильным, когда я вызываю метод редактирования. я также могу редактировать значения в своей программе. не будет работать только обратная запись в текстовый файл (ТОЛЬКО в нижнем фрагменте кода! в верхнем он работает отлично).
Ответ №1:
Я не эксперт по JSON, но у encode
метода возникли проблемы с благословенной ссылкой. Использование неиспользованной ссылки кажется допустимым обходным путем:
if($Count == $ID){#if line of data found, who is going to be edited
print WF $json->encode( {%$self} )."n";
...
Комментарии:
1. Вот почему я включил это —> $ json-> allow_blessed(1);<— ваш код не будет работать, в любом случае спасибо за вашу помощь.
2. хм, но ваше право … были проблемы из-за благословенной ссылки… я сохранил данные в скалярном формате tmp и закодировал его… теперь это работает. спасибо :))
3. Просматривая
JSON
документы,JSON::allow_blessed
будет подавлять исключения при передаче объекта blessed вencode
. Но для кодирования благословенного объекта требуется, чтобы вы (1) также вызвали$json->convert_blessed(1)
и (2) реализовалиTO_JSON
метод object, который возвращает значение для encode. Это значение также должно быть неиспользованной ссылкой.
Ответ №2:
Я поддерживаю идею (как вы уже поняли), что проблема заключается в благословенной ссылке, однако я предлагаю вам другое решение (в конце концов, это Perl: TIMTOWTDI). Модуль Acme::Damn позволяет разблокировать (то есть проклясть) объект. Поэтому вы должны уметь:
print WF $json->encode(damn($self))."n";
Также я почувствовал, что должен поделиться, поскольку у метода такое умное название.
Ответ №3:
Следуя предложению последнего mob, вот простой пример того, как сериализовать благословенные ссылки.
package Node;
sub new {
my $class = shift;
bless { @_ }, $class;
}
sub TO_JSON {
my $self = shift;
return { class => 'Node', data => { %$self } };
}
package main;
use JSON;
my $node_hash = {
a => [ 'text1', 'text2' ],
b => [ 'what', 'is', 'this' ],
c => [ Node->new(some => 'data') ],
};
print to_json($node_hash, { convert_blessed => 1 });
Однако вам нужно обратить внимание на декодирование. Можно использовать filter_json_single_key_object для реализации полного цикла.