我应该如何在Perl中序列化代码引用?

时间:2010-10-02 09:32:04

标签: perl serialization function store

我希望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 个答案:

答案 0 :(得分:1)

代码引用不能简单地序列化。文件句柄,数据库连接以及任何具有外部资源的东西都不能简单地序列化。

在序列化这些项目时,您必须以可以重新创建它们的方式对其进行描述。例如,您可以将文件句柄序列化为路径,将偏移量或代码引用序列化为引用所指向的函数名称。

您可以使用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";

当然,这意味着您无法序列化匿名引用,并且序列化数据只能由以相同方式实现命名函数的程序可靠地使用。

如果您发现自己需要这样做,那么最好使用类而不是简单的代码引用。

答案 1 :(得分:1)

在设置其中一个配置值之前,您忽略了加载Storable模块。

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

答案 2 :(得分:0)

您还需要设置

$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}();