in reply to Re^7: DBM::Deep Problem
in thread DBM::Deep Problem
#!perl use Test::More no_plan; use strict; BEGIN { require_ok('Tie::Hash') } my @RECORDER; BEGIN { package Tie::Test; use base 'Tie::StdHash'; sub FETCH { my $self = shift; push @RECORDER, [$self, 'FETCH', @_]; $self->SUPER::FETCH(@_); } sub STORE { my $self = shift; push @RECORDER, [$self, 'STORE', @_]; $self->SUPER::STORE(@_); } } tie my %tiedhash, Tie::Test::; ## direct assignments properly call STORE @RECORDER = (); $tiedhash{flintstone} = 'fred'; is_deeply(\@RECORDER, [[tied %tiedhash, 'STORE', 'flintstone', 'fred'] +]); ## however, this autoviv *should* first call FETCH to notice ## that $tiedhash{rubble} is undef, then call STORE to ## try to put a new anon hash into the slot (it doesn't), then ## call FETCH to fetch this new anon hash (it doesn't), which ## is then used to plug barney with short. ## ## instead, it calls FETCH to notice that $tiedhash{rubble} is undef, ## and then STORE with a newly populated hashref that already has ## { barney => 'short' }. I say this is a bug! @RECORDER = (); $tiedhash{rubble}{barney} = 'short'; is($_, tied %tiedhash, 'action is against %tiedhash') for map $_->[0], @RECORDER; is($RECORDER[0][1], 'FETCH', 'first op is a fetch') and is($RECORDER[0][2], 'rubble', 'fetching key of rubble') and is($RECORDER[1][1], 'STORE', 'second op is a store') and is($RECORDER[1][2], 'rubble', 'storing key of rubble') and isa_ok($RECORDER[1][3], 'HASH', 'storing an anonhash') and is(keys %{$RECORDER[1][3]}, 0, 'empty anonhash') and is($RECORDER[2][1], 'FETCH', 'third op is a fetch') and is($RECORDER[2][2], 'rubble', 'fetching key of rubble') and is(@RECORDER, 3, 'only 3 steps'); use Data::Dumper; diag(Dumper [\@RECORDER]);
-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply.
|
|---|