2010-10-02 5 views
2

Je souhaite nstore un hachage Perl qui contient également une référence de code. Suite à cette perldoc j'ai écrit quelque chose comme ceci:Comment sérialiser les références de code en Perl?

use strict; 
use warnings; 
local $Storable::Deparse = 1; 
my %hash = (... CODE => ...); 
nstore (\%hash, $file); 

Je reçois un avertissement disant Name "Storable::Deparse" used only once: possible typo at test4.pl line 15.. Je suppose que je pourrais spécifiquement supprimer cet avertissement, mais je me demande si je fais quelque chose de mal.

Notez que cette question porte sur one. Différents titres à distinguer entre les deux seront les bienvenus.

Répondre

1

Vous avez oublié de charger le module stockable, avant de l'une de ses valeurs de configuration.

use strict; 
use warnings; 
use Storable qw(nstore); 
local $Storable::Deparse = 1; 
my %hash = (... CODE => ...); 
nstore (\%hash, $file); 
1

Les références de code ne peuvent pas être simplement sérialisées. Les handles de fichiers, les connexions à la base de données et tout ce qui a des ressources externes ne peuvent pas être simplement sérialisés.

Lors de la sérialisation de ces éléments, vous devez les décrire de manière à pouvoir les recréer. Par exemple, vous pouvez sérialiser un handle de fichier comme un chemin et un offset ou une référence de code comme le nom de la fonction pointée par la référence.

Vous pouvez trouver le nom du sous-programme un point de référence de code avec Sub::Identify:

#!/usr/bin/perl 

use strict; 
use warnings; 

use Sub::Identify qw/sub_fullname/; 

sub foo {} 

my $r = \&foo; 

print sub_fullname($r), "\n"; 

Bien sûr, cela signifie que vous ne pouvez pas sérialiser références anonymes et les données sérialisés ne peut être utilisé de manière fiable par des programmes qui mettent en œuvre les fonctions nommées de la même manière.

Si vous avez besoin de faire cela, il vaut probablement mieux utiliser une classe plutôt qu'une simple référence de code.

+0

+1 Merci. J'ai finalement décidé d'utiliser un objet à la place. –

0

Vous devez également définir

$Storable::Eval = 1; 

ainsi:

#! perl 

use strict; 
use warnings; 

use Storable qw /nstore retrieve/; 


local $Storable::Deparse = 1; 
local $Storable::Eval = 1; 

my %hash = (CODE => sub {print "ahoj\n";}); 


nstore (\%hash, 'test'); 
my $retrieved = retrieve ('test'); 

$retrieved->{CODE}(); 
Questions connexes