Desde la sección "Code References" de la documentación para almacenar (con énfasis añadido):
Desde almacenable versión 2.05, las referencias de código pueden ser serializados con la ayuda de B::Deparse
. Para habilitar esta función, configure $Storable::Deparse
en un valor verdadero. Para habilitar la deserialización, $Storable::Eval
debe establecerse en un valor verdadero. Tenga en cuenta que la deserialización se realiza a través de eval
, lo cual es peligroso si el archivo Almacenable contiene datos maliciosos.
En la demostración a continuación, un proceso secundario crea el hash de subs anónimos. A continuación, el elemento primario, en un espacio de proceso y dirección por separado, por lo que no puede ver %dispatch
, lee la salida de freeze
de la misma forma que podría hacerlo desde un archivo en el disco.
#! /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;
}
Salida:
Hi!
Holla!
Yo!
En lugar de guardar los submarinos compilados reales, que podrían salvar el texto * * de los submarinos y, a continuación, re-eval en coderefs en el nuevo proceso. – Ether
Sí, pensé en eso. Pero me gustaría poder guardar los subs compilados por razones estéticas. :-p –
Todas las técnicas que conozco usan B :: Deparse para traducir la referencia del código nuevamente al código fuente de Perl. Este proceso puede no devolverle el mismo código fuente con el que comenzó. No creo que esto te compre mucho más que simplemente guardar el texto original. –