如何在Perl中序列化闭包?

时间:2010-10-02 09:53:57

标签: perl serialization function closures store

我认为最好问一个例子:

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;
        }

但是{sub} $x从未定义过。我希望sub_generator生成的子将在生成时将$x替换为其实际值。我该怎么解决这个问题?

请注意,此问题与此one有关。

1 个答案:

答案 0 :(得分:5)

不幸的是,我不认为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搬运工邮件列表上查看此帖子Storable and Closures。它确认了我对Storable和闭包的看法。

/ I3az /