如何在Perl中序列化闭包? [英] How can I serialize a closure in Perl?

查看:125
本文介绍了如何在Perl中序列化闭包?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为这可能是最好的例子:

  use strict; 
使用警告;
use 5.010;
使用可存储qw(nstore检索);

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 strict'refs';
my($ y)= @_;
return $ x + $ y;
}

$ x 从来没有在这个子定义。我希望 sub_generator 生成的子代会生成 $ x ,替换为它的实际值。我应该如何解决这个问题?



请注意,此问题与此一个有关。 。

解决方案

不幸的是,我不认为 可存储 适用于闭包。但是有其他CPAN模块将序列化闭包。例如。 Data :: Dump :: Streamer

 使用5.012; 
使用警告;
使用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 $ serialized = Dump($ sub) - > Out;
my $ copy = do {
my $ CODE1 = undef;
eval $ serialized;
$ CODE1;
};

say $ copy->(2); #gives 1002
say $ sub>(1); #still gives 1001

这是打印时序列化代码的样子, say Dump $ sub;

  my 
$ x = 1000;
$ CODE1 = sub {
使用警告;
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;
};



更新
$ b

查看此主题可存储和关闭在Perl5门户邮件列表。它确认了我对 可存储 的思考和关闭。



/ I3az /


I think this might be best asked using an example:

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

When I dump /tmp/sub.store I see:

$VAR1 = sub {
            package Storable;
            use warnings;
            use strict 'refs';
            my($y) = @_;
            return $x + $y;
        }

But $x is never defined in this sub. I would expect that the sub generated by sub_generator will have $x replaced with its actual value upon generation. How should I solve this?

Note this question relates to this one.

解决方案

Unfortunately I don't think Storable works with closures. However there are other CPAN modules that will serialise a closure. For eg. 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

This is what the serialised code looks like when printed here, 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;
         };


Update

See this thread Storable and Closures on the Perl5 porters mailing list. It confirms what I thought about Storable and closures.

/I3az/

这篇关于如何在Perl中序列化闭包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆