Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Monday August 13, 2007
11:18 PM

DBM::Deep: Cannot store something that is tied

[ #34103 ]

I ran into this problem and it's plagued me for a couple weeks. I was playing with with stuff to store a bunch of stuff in a DBM::Deep file, and I'd do something to cause an error "DBM::Deep: Cannot store something that is tied". I'd change around some syntax and it would disappear. I've sorta solved the problem, but it doesn't really look like a real solution.

I figured that some other module I was using was supplying a tied object. Config::IniFiles seemed a likely candidate because it has tie methods inside it, so for awhile I blamed it and thought I had a workaround.

But the problem came back, this time without Config::IniFiles. Damn you Karl Rove!

It turns out that I was taking some data out of a DBM::Deep object and either moving it back into the object in a different form or trying to put it in a different DBM::Deep object:

#!/usr/bin/perl
 
use Data::Dumper;
use DBM::Deep;
 
my $db = DBM::Deep->new( 'foo.db' );
 
$db->{'foo'} = [ qw(a b c) ];
 
my $array = $db->{'foo'};
 
print Dumper( $array );
 
$db->{'bar'} = $array;
 
__END__

Okay, that's no good. This eluded me for a while because tied doesn't work on $array, so when I was trying debugging statements such as print ... if tied $array, I never saw that output. I was just guessing about who was causing the problem.

I read through the DBM::Deep docs a couple of times looking for a warning about this, but I didn't find it. I figured that there must be a way to untie or de-objectify $array, so I started trying things. It turns out export will turn the DBM::Deep thingy into a regular thingy. I got sidetracked by the line in the docs that said 'Calling the "export()" method on an existing DBM::Deep object will return a reference to a new in-memory copy of the database.' I figured that meant that I'd just get another DBM::Deep object. However, the next sentence has "...are all exported to standard Perl objects."

#!/usr/bin/perl
 
use Data::Dumper;
use DBM::Deep;
 
my $db = DBM::Deep->new( 'foo.db' );
 
$db->{'foo'} = [ qw(a b c) ];
 
my $array = $db->{'foo'}->export;
 
print Dumper( $array );
 
$db->{'bar'} = $array;
 
__END__

It gets trickier though. Watch this problem barge back into the program. I export to get the stuff back into a regular Perl data structure, then store it in the DBM::Deep object. I try to take that same reference and store it again, but it's been re-blessed into DBM::Deep!

#!/usr/bin/perl
 
use Data::Dumper;
use DBM::Deep;
 
my $db = DBM::Deep->new( 'foo.db' );
 
$db->{'foo'} = [ qw(a b c) ];
 
my $array = $db->{'foo'}->export;
 
$db->{'bar'} = $array; # this works
 
$db->{'baz'} = $array; # it's a DBM::Deep thingy again

So, I could get rid of the temporary variable:

$db->{'bar'} = $db->{'foo'}->export;
 
$db->{'baz'} = $db->{'foo'}->export;

That seems like it works, but it doesn't really work. Everyone of those references are deep copies, meaning that when I meant to store the data once, I'm actually recreating it. Worse than that, it's only going ot update in one place.

I haven't worked around that last bit yet, and it will probably mean I'll have to think a lot harder about the program.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.