I believe this is a known perl bug (Can't use FETCH while inside a FETCH).
CC'd to perl5-porters for confirmation.
Tim.
On Fri, Mar 28, 2003 at 04:27:41PM +0100, Silvio Wanka wrote:
>
> Hi,
>
> there is a strange problem with usage of DBI inside the FETCH method
> of a tied hash. I have inherited the maintenance of a perl module
> which contains some configuration data and was filled in the past
> by hand but currently all data are maintained by a database
> and the data are to many to generate the module now for backward
> compatibility. So I have changed the module that its new method
> returns now a ref to a tied hash and the data is fetching on
> request from the database using DBIx::Recordset (was not my
> choice). Because the module exists only for backward compatibility
> I can't change any code, where it is used. Some values of
> this hash are again hash ref's and in this case the problem
> occurs. Here the stripped code to simple reproduce the bug:
>
> #################################################################
> package Tie::HashTest;
>
> require Tie::Hash;
> require DBI;
>
> @ISA = qw(Tie::StdHash);
>
> sub FETCH ($$)
> {
> my $self = shift;
> my $key = shift;
>
> DBI->connect('dbi:NullP:','','')
> if $key eq 'dbi';
>
> return {true => 1};
> }
>
> package main;
>
> my %h;
>
> tie %h, 'Tie::HashTest';
>
> print STDERR 'DBI-VERSION: ', $DBI::VERSION, "\n\n";
>
> for my $key (qw(other dbi))
> {
> my $val = $h{$key};
>
> print STDERR $key, "\t", $val->{true};
> print STDERR ':', $h{$key}->{true}, "\n";
> }
> #################################################################
>
> If the returned hash ref will be first assigned to a scalar
> then all works but if the returned hash ref will be directly
> dereferenced it crashes:
>
> DBI-VERSION: 1.21
>
> other 1:1
> dbi 1Can't use an undefined value as a HASH reference at dbi_tst.pl line 32.
>
> I have also tried the current DBI version:
>
> DBI-VERSION: 1.35
>
> other 1:1
> dbi 1Can't use an undefined value as a HASH reference at dbi_tst.pl line 32.
>
>
> but it is the same. I use Perl 5.6.1 without thread support build on
> HP-UX 10.20 using the HP ANSI-C compiler. But I have tried it with
> other Perl build (5.5.3 on HP-UX, 5.6.1 build with GCC on HP-UX and
> Solaris) and other DBD-drivers it is always the same.
>
> I have also tried to use a existing DBIx::Recordset as DataSource (in this
> case DBI::connect will not called again in DBIx::Recordset::Setup...), but
> it does not help because some other DBI methods are called. The only
> solution is at the moment, to create the DBIx::Recordset object during
> TIEHASH call, save it in the returned ref. and overload in the FETCH method
> the new method of the used DBIx::Recordset subclass by
>
> local *<DBIx::Recordset subclass>::new = sub {return <saved obj>};
>
> because the API of the methods I use for data fetching don't have the
> possibility to hand over the DBIx::Recordset object. This is very
> tricky and unsatisfyingly (I don't like which kind of code).
>
> regards, Silvio