微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在Perl中序列化闭包?

我认为使用一个例子可能是最好的问题:

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生成的sub将在生成时将$x替换为其实际值.我该怎么解决这个问题?

注意这个问题与这个one有关.

解决方法

不幸的是,我不认为 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

这是在这里打印时序列化代码的样子,比如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 /

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐