我有一个 Perl 程序,它从输入文件生成解析规则作为 subs。潜艇被匿名定义并放入散列中。现在,我想导出该哈希,以及所有子程序,然后稍后再次加载它们以用于不同的程序。
我该怎么做呢?有没有办法提取每个子的代码,或者我可以复制散列存在的内存块,然后当我稍后再次加载它时将其转换为散列?
提前致谢。
我有一个 Perl 程序,它从输入文件生成解析规则作为 subs。潜艇被匿名定义并放入散列中。现在,我想导出该哈希,以及所有子程序,然后稍后再次加载它们以用于不同的程序。
我该怎么做呢?有没有办法提取每个子的代码,或者我可以复制散列存在的内存块,然后当我稍后再次加载它时将其转换为散列?
提前致谢。
除了其他 Perl 类型之外,KiokuDB还可以处理存储代码引用。各种YAML模块、Data::Dump::Streamer甚至 Data::Dumper 也可以。
从可存储文档的“代码参考”部分(特别强调):
从 Storable 2.05 版本开始,CODE 引用可以在
B::Deparse
. 要启用此功能,请设置$Storable::Deparse
为真值。要启用反序列化,$Storable::Eval
应设置为真值。请注意,反序列化是通过 完成的eval
,如果 Storable 文件包含恶意数据,这是很危险的。
在下面的演示中,一个子进程创建了匿名 subs 的散列。然后父进程——在一个完全独立的进程和地址空间中,所以它看不到%dispatch
——读取输出freeze
的方式与你从磁盘上的文件中读取的方式相同。
#! /usr/bin/perl
use warnings;
use strict;
use Storable qw/ freeze thaw /;
my $pid = open my $fh, "-|";
die "$0: fork: $!" unless defined $pid;
if ($pid == 0) {
# child process
my %dispatch = (
foo => sub { print "Yo!\n" },
bar => sub { print "Hi!\n" },
baz => sub { print "Holla!\n" },
);
local $Storable::Deparse = 1 || $Storable::Deparse;
binmode STDOUT, ":bytes";
print freeze \%dispatch;
exit 0;
}
else {
# parent process
local $/;
binmode $fh, ":bytes";
my $frozen = <$fh>;
local $Storable::Eval = 1 || $Storable::Eval;
my $d = thaw $frozen;
$d->{$_}() for keys %$d;
}
输出:
你好! 哈拉! 哟!