Написать анонимный сабвуфер на Perl в файл для последующего использования - PullRequest
7 голосов
/ 04 февраля 2010

У меня есть программа на Perl, которая генерирует правила синтаксического анализа как подпрограммы из входного файла. Подпрограммы анонимно определены как вставка в хеш. Теперь я хочу экспортировать этот хеш со всеми подпрограммами, а затем снова загрузить их для использования в другой программе.

Как мне это сделать? Есть ли какой-нибудь способ извлечь код каждого сабвуфера или я могу скопировать блок памяти, в котором существует хеш, и затем преобразовать его в хеш, когда я снова загружу его позже?

Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 04 февраля 2010

KiokuDB может обрабатывать хранение ссылок на код в дополнение к другим типам Perl. То же самое можно сказать о различных модулях YAML , Data :: Dump :: Streamer и даже Data :: Dumper.

2 голосов
/ 05 февраля 2010

Из «Кодовых ссылок» раздела «Сохраняемая документация» (с дополнительным акцентом):

Начиная с версии 2.05, доступной для хранения, ссылки на КОДЫ могут быть сериализованы с помощью B::Deparse. Чтобы включить эту функцию, установите $Storable::Deparse в истинное значение. Чтобы включить десериализацию, $Storable::Eval должно быть установлено в истинное значение. Имейте в виду, что десериализация выполняется через eval, что опасно, если в хранимом файле содержатся вредоносные данные.

В демонстрации ниже дочерний процесс создает хэш анонимных подпрограмм. Затем родительский объект - в совершенно отдельном процессе и адресном пространстве, поэтому он не может видеть %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;
}

Выход:

Hi!
Holla!
Yo!
...