7

Ho un programma Perl che genera regole di analisi come sottotitoli da un file di input. I sottotitoli sono definiti in modo anonimo e inseriti in un hash. Ora, voglio esportare quell'hash, con tutti i sottotitoli e poi caricarli di nuovo in seguito per utilizzarli con un programma diverso.Scrive un sub anonimo in Perl su un file per uso futuro

Come faccio a fare questo? Esiste un modo per estrarre il codice di ciascun sottotitolo o posso copiare il blocco di memoria in cui è presente l'hash e quindi lanciarlo come hash quando lo carico di nuovo in seguito?

Grazie in anticipo.

+0

Invece di salvare i sottotitoli effettivi compilati, è possibile salvare il testo * * dei sottomarini, e poi ri-valuta in coderefs nel nuovo processo. – Ether

+0

Sì, ci ho pensato. Ma mi piacerebbe essere in grado di salvare i sottotitoli compilati per ragioni estetiche. :-p –

+0

Tutte le tecniche che conosco di uso B :: Deparse per tradurre il codice di riferimento nel codice sorgente Perl. Questo processo potrebbe non restituirti lo stesso codice sorgente con cui hai iniziato. Non penso che questo ti compri molto semplicemente salvando il testo originale. –

risposta

2

Dalla sezione "Code References" della documentazione memorizzabili (con enfasi aggiunta):

Dal riponibile versione 2.05, i riferimenti codice può essere serializzato con l'aiuto di B::Deparse. Per abilitare questa funzione, impostare $Storable::Deparse su un valore true. Per abilitare la deserializzazione, $Storable::Eval deve essere impostato su un valore true. Tenere presente che la deserializzazione viene eseguita tramite eval, che è pericoloso se il file di archiviazione contiene dati dannosi.

Nella demo di seguito, un processo figlio crea l'hash di sottotitoli anonimi. Quindi il genitore-in un processo completamente separato e lo spazio degli indirizzi, quindi non può vedere %dispatch -reads l'output da freeze nello stesso modo che si potrebbe da un file su 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; 
} 

uscita:

Hi! 
Holla! 
Yo!
+0

e posso semplicemente scrivere '$ congelato' in un file di testo? e non preoccuparti, disinfetterò i miei input. Ho imparato questo da XKCD: D –

+0

@Mechko Sì, nel tuo codice, dovresti scrivere l'output su un file su disco e poi leggerlo in seguito. Ho modificato la demo in modo da assomigliare a entrambi i lati della pipeline. –

Problemi correlati