Запишите анонимный sub в Perl в файл для более позднего использования

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

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

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

7
задан Ritwik Bose 4 February 2010 в 17:08
поделиться

2 ответа

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

Начиная с версии 2.05 Storable, ссылки CODE могут быть сериализованы с помощью 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!
2
ответ дан 7 December 2019 в 10:01
поделиться

Я хотел использовать Система. Сеть. HttpContext. Ток. Ответ вместо Response.redirect, и необходимый удобство закодировать как Response.redirect. Я определил свойство только для чтения с именем Response , чтобы затенить оригинал в базовом классе. Я не мог использовать переопределения, так как это свойство не может быть переопределено. Очень удобно:)

-121--919013-

Использование + = и + в массивах PowerShell создает копию массива при каждом его использовании. Это нормально, если список/массив действительно велик. В этом случае рассмотрите возможность использования общего списка

C:\> $list = new-object 'System.Collections.Generic.List[string]'
C:\> $list.Add('a')
C:\> $list.Add('b')
C:\> $list.Insert(0,'aa')
C:\> $list
aa
a
b

Обратите внимание, что в этом сценарии необходимо использовать методы Add/Insert. Если вернуться к использованию + = , общий список будет скопирован обратно в объект [] .

-121--2598264-

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

4
ответ дан 7 December 2019 в 10:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: