Написать анонимный сабвуфер на Perl в файл для дальнейшего использования
У меня есть Perl-программа, которая генерирует правила синтаксического анализа как подпрограммы из входного файла. Подпрограммы анонимно определены как вставка в хеш. Теперь я хочу экспортировать этот хэш со всеми подпрограммами, а затем снова загрузить их для использования в другой программе.
Как мне это сделать? Есть ли какой-нибудь способ извлечь код каждого сабвуфера, или я могу скопировать блок памяти, в котором существует хеш, и затем преобразовать его в хэш, когда я снова загружу его позже?
Заранее спасибо.
2 ответа
Из раздела "Ссылки на код" в документации по хранимым данным (с дополнительным акцентом):
Начиная с версии 2.05, ссылки на CODE могут быть сериализованы с помощью
B::Deparse
, Чтобы включить эту функцию, установите$Storable::Deparse
к истинному значению. Чтобы включить десериализацию,$Storable::Eval
должно быть установлено в истинное значение. Помните, что десериализация осуществляется черезeval
, что опасно, если файл Storable содержит вредоносные данные.
В демонстрации ниже дочерний процесс создает хэш анонимных подпрограмм. Затем родитель - в совершенно отдельном процессе и адресном пространстве, поэтому он не может видеть %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;
}
Выход:
Привет! Holla! Эй!
KiokuDB может обрабатывать ссылки на код в дополнение к другим типам Perl. То же самое можно сказать о различных модулях YAML, Data:: Dump:: Streamer и даже Data::Dumper.