views:

71

answers:

3

I wish to nstore a Perl hash which also contains a code reference. Following this perldoc I wrote something like this:

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

I get a warning saying Name "Storable::Deparse" used only once: possible typo at test4.pl line 15.. I guess I could specifically suppress this warning, but it makes me wonder if I'm doing anything wrong.

Note this question relates to this one. Different titles to distinguish between the two will be most welcomed.

+1  A: 

Code references cannot be simply serialized. File handles, database connections, and anything that has external resources cannot be simply serialized.

When serializing such items, you must describe them in such a way that they can be recreated. For instance, you might serialize a file handle as a path and an offset or a code reference as the name of function the reference was pointing to.

You can find the name of the subroutine a code reference points to with 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";

Of course, this means you cannot serialize anonymous references and the serialized data can only reliably be used by programs that implement the named functions in the same way.

If you find yourself needing to do this, you are probably better off using a class instead of a simple code reference.

Chas. Owens
+1 Thank you. I finally decided to use an object instead.
David B
A: 

You also need to set

$Storable::Eval = 1;

thus:

#! 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}();
jira
+1  A: 

You have neglected to load the Storable module, before setting one of its config values.

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