Как я могу сериализировать закрытие в Perl?
-
27-09-2019 - |
Вопрос
Я думаю, что это может лучше попросить использовать пример:
use strict;
use warnings;
use 5.010;
use Storable qw(nstore retrieve);
local $Storable::Deparse = 1;
local $Storable::Eval = 1;
sub sub_generator {
my ($x) = @_;
return sub {
my ($y) = @_;
return $x + $y;
};
}
my $sub = sub_generator(1000);
say $sub->(1); # gives 1001
nstore( $sub, "/tmp/sub.store" );
$sub = retrieve("/tmp/sub.store");
say $sub->(1); # gives 1
Когда я дамп /tmp/sub.store
Я понимаю:
$VAR1 = sub {
package Storable;
use warnings;
use strict 'refs';
my($y) = @_;
return $x + $y;
}
Но $x
никогда не определяется в этом под. Я бы ожидал, что подгруппированный sub_generator
буду иметь $x
заменено его фактической стоимостью по генерации. Как мне это решить?
Обратите внимание на этот вопрос относится к этому один.
Решение
К сожалению, я не думаю Storable
Работает с закрытиями. Однако есть и другие модули CPAN, которые будут сериализировать закрытие. Например, Data::Dump::Streamer
use 5.012;
use warnings;
use Data::Dump::Streamer;
sub sub_generator {
my ($x) = @_;
return sub {
my ($y) = @_;
return $x + $y;
};
}
my $sub = sub_generator(1000);
say $sub->(1); # gives 1001
my $serialised = Dump( $sub )->Out;
my $copy = do {
my $CODE1 = undef;
eval $serialised;
$CODE1;
};
say $copy->(2); # gives 1002
say $sub->(1); # still gives 1001
Это то, что сериализованный код выглядит когда напечатано здесь, say Dump $sub;
:
my ($x);
$x = 1000;
$CODE1 = sub {
use warnings;
use strict 'refs';
BEGIN {
$^H{'feature_unicode'} = q(1);
$^H{'feature_say'} = q(1);
$^H{'feature_state'} = q(1);
$^H{'feature_switch'} = q(1);
}
my($y) = @_;
return $x + $y;
};
Обновлять
Смотрите эту тему Хранимые и замыкания в списке рассылки Perl5 Porters. Это подтверждает, о чем я думал о Storable
и замыкание.
/ I3Az /
Не связан с StackOverflow