Как я должен сериализовать ссылки на код в Perl? - PullRequest
2 голосов
/ 02 октября 2010

Я хочу nstore хеш Perl, который также содержит ссылку на код. После этого perldoc я написал что-то вроде этого:

use strict;
use warnings;
local $Storable::Deparse = 1; 
my %hash = (... CODE => ...);
nstore (\%hash, $file);

Я получаю предупреждение, говорящее Name "Storable::Deparse" used only once: possible typo at test4.pl line 15.. Думаю, я мог бы специально подавить это предупреждение, но это заставляет меня задуматься, не делаю ли я что-то не так.

Обратите внимание, что этот вопрос относится к этому one . Различные названия, чтобы различать два, будут приветствоваться.

Ответы [ 3 ]

1 голос
/ 02 октября 2010

Вы забыли загрузить модуль Storable перед настройкой одного из его значений конфигурации.

use strict;
use warnings;
use Storable qw(nstore);
local $Storable::Deparse = 1; 
my %hash = (... CODE => ...);
nstore (\%hash, $file);
1 голос
/ 02 октября 2010

Ссылки на код нельзя просто сериализовать. Файловые дескрипторы, соединения с базой данных и все, что имеет внешние ресурсы, нельзя просто сериализовать.

При сериализации таких предметов вы должны описать их так, чтобы их можно было воссоздать. Например, вы можете сериализовать дескриптор файла как путь, а смещение или ссылку на код - как имя функции, на которую ссылалась ссылка.

Вы можете найти имя подпрограммы, на которую ссылается код, с помощью Sub::Identify:

#!/usr/bin/perl

use strict;
use warnings;

use Sub::Identify qw/sub_fullname/;

sub foo {}

my $r = \&foo;

print sub_fullname($r), "\n";

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

Если вам понадобится это сделать, вам, вероятно, лучше использовать класс вместо простой ссылки на код.

0 голосов
/ 02 октября 2010

Вам также нужно установить

$Storable::Eval = 1;

следующим образом:

#! perl

use strict;
use warnings;

use Storable qw /nstore retrieve/;


local $Storable::Deparse = 1; 
local $Storable::Eval = 1; 

my %hash = ( CODE => sub {print "ahoj\n";});


nstore (\%hash, 'test');
my $retrieved = retrieve ( 'test');

$retrieved->{CODE}();
...