I'm using TIEHASH to make persistant objects. Objects are marked if they're dirty and then flushed before the script ends. The TIEHASH uses two components, %l which is the script's object cache and %f which is a GDBM_File and objects are Data::Dump'd before they're stored.

Assume %l = { 0=>{oid=>0, hi=>there}, 1=>{oid=>1, hi=>woof}} and that %o is my TIE'd object store.

This works:

print "$o{0} $o{0}->{hi}\n";
But this gives the following error:
print "$o{0}->{hi}\n";
Can't use an undefined value as a HASH reference at t2.pl line 27.

Why does pwotie's FETCH work ok with $o{0} called first, but fail when $o{0}->{hi} is called first?

Here's my source for you to try yourself:

{ # implements persistence based on dirty and tied persistence in %o package Pwo; our %o; our $keep; sub flush { for (values %o) { if($_->{dirty}) { delete $_->{dirty}; $keep->keep($_); print "k: $_->{hi} "; }}} sub Pwo { my($class,$filename)=@_; $class=ref($class) || $class; $keep=tie(%o, pwotie, $filename) || die "Pwo: Persistence failed: ", +join(', ',@dbm)," -- error:$!\n"; my $self={ 'o'=>\%o, }; bless $self,$class; # if this is a new install we need to load the base objects print "o{0}=$o{0}\n"; bootstrap() unless defined $o{0}; print "o{0}=$o{0} 0=$o{0}->{hi} 1=$o{1}->{hi}\n"; return $self; } sub bootstrap { print "bs\n"; $o{0}={hi=>there, how=>'are you', dirty=>1, oid=>0}; $o{1}={hi=>"woof",dirty=>1,oid=>1}; } } { package pwotie; use Data::Dump qw(dump); use GDBM_File; sub TIEHASH { my ($class,$filename)=@_; $Result = tie(%f, 'GDBM_File', $filename, 2, 0640); ## duno what's wr +ong with my perl -- GDBM_WRCREAT=2 for me. if (! $Result){ print "\n\nCould not open GDBM file '$filename': $!\n"; } return bless { file=>$filename, f => \%f, l => () }, $class; } sub keep {$_[0]->{f}{$_[1]->{oid}}=dump($_[1]); print "sto: ".dump($_[ +1])."\n";} sub STORE { my ($this, $key, $value)=@_; return $this->{l}{$key}=($value); } sub FETCH { my ($this, $key)=@_; return $this->{'l'}{$key} if exists $this->{'l'}{$key}; print "trying f's $key: $this->{f}{$key}\n"; $this->{'l'}{$key}=eval($this->{f}{$key}); return $this->{'l'}{$key}; } sub FIRSTKEY { my $a = scalar keys %{$_[0]->{l}}; each %{$_[0]->{l}}; +} sub NEXTKEY { each %{$_[0]->{l}}; } sub EXISTS { my ($this, $key)=@_; return exists $this->{f}{$key};} sub DELETE {my ($this, $key)=@_; delete $this->{l}{$key}; delete $this->{f}{$key}; } sub CLEAR {my ($this)=@_; undef %{$this->{l}}; undef %{$this->{f}}; } } $p=Pwo->Pwo("tst.db" ); $p->flush();
I'm using perl, v5.6.1 built for MSWin32-x86-multi-thread

Binary build 631 provided by ActiveState Tool Corp. http://www.ActiveState.com
Built 17:16:22 Jan 2 2002


In reply to TIEHASH hiccup? by jhanna

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.