Vom "Code References" Abschnitt der speicherbaren Dokumentation (mit Hervorhebungen):
Seit Storable Version 2.05 können CODE Referenzen mit Hilfe von B::Deparse
serialisiert werden. Um diese Funktion zu aktivieren, setzen Sie $Storable::Deparse
auf einen wahren Wert. Um die Deserialisierung zu aktivieren, sollte $Storable::Eval
auf einen wahren Wert gesetzt werden. Beachten Sie, dass die Deserialisierung über eval
erfolgt, was gefährlich ist, wenn die speicherbare Datei schädliche Daten enthält.
In der folgenden Demo erstellt ein untergeordneter Prozess den Hash der anonymen Subs. Dann die Eltern-in einem völlig separaten Prozess-und Adressraum, so dass es nicht sehen %dispatch
- liest die Ausgabe von freeze
auf die gleiche Weise, wie Sie möglicherweise von einer Datei auf der Festplatte.
#! /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;
}
Ausgang:
Hi!
Holla!
Yo!
Anstatt der tatsächlichen kompilierte subs retten, könnten Sie den * Text * der U-Boote speichern, und dann erneut eval sie in coderefs in dem neuen Prozess. – Ether
Ja, ich habe daran gedacht. Aber ich möchte die kompilierten Subs aus ästhetischen Gründen speichern können. :-p –
Alle Techniken, die ich kenne, verwenden B :: Deparse, um die Code-Referenz zurück in Perl-Quellcode zu übersetzen. Dieser Prozess gibt möglicherweise nicht denselben Quellcode zurück, mit dem Sie begonnen haben. Ich glaube nicht, dass Sie dadurch viel Geld sparen, indem Sie einfach den eigentlichen Originaltext speichern. –