Front page | perl.perl5.porters |
Postings from March 2001
[ID 20010329.009] FETCHing "directly" from a complex tied hashevaluates to undef
From:
Ben Low
Date:
March 29, 2001 20:17
Subject:
[ID 20010329.009] FETCHing "directly" from a complex tied hashevaluates to undef
Message ID:
3AC408D5.2083AEE4@snrc.uow.edu.au
This is a bug report for perl from ben@snrc.uow.edu.au,
generated with the help of perlbug 1.26 running under perl 5.00503.
-----------------------------------------------------------------
[Please enter your report here]
The following has been confirmed w/ perl 5.004_04, 5.005_02, 5.005_03.
I have endeavoured to check all available perl docs, to no avail.
Summary:
FETCHing "directly" from a complex tied hash evaluates to undef, eg
$r = $h{k}; print $r->{x}; # works ok
print $h{k}->{x}; # Can't use an undefined value as a HASH ref...
Details:
Below is part of a module which provides a "defaulting" tied
hash, that is on FETCHing it returns either the value from the tied
hash or a corresponding value from another tied hash (the "defaults").
In the following, the top defaulting hash is called ConfigHash, and the
secondary, defaults, hash is called SHash (Stripped Hash).
The problem is that when the second tied hash is accessed "directly",
the valid value returned from the FETCH gets turned into an undef.
The extract below has a "test case" to show the problem.
#!/usr/bin/perl -w
use strict;
{
package SHash; # 'stripped' hash (case-insensitive, whitespace,_
removed)
use Tie::Hash;
use vars qw/@ISA/;
@ISA = qw/Tie::StdHash/; # inherit the standard hash methods
# my SHash methods to process the hash keys go here...
package ConfigHash;
use Tie::Hash;
use vars qw/@ISA/;
@ISA = qw/SHash/;
# don't want the DEFAULTs to show up in the tied hash, so they
# are kept independantly of the tied objects
# - this is a "class private" structure
my %DEFAULTS = ();
sub w { my $i=0;while (caller($i++)) { print STDERR '-' }; print STDERR
(caller(1))[3] . '(' . join(',', @_) . ")\n" }
sub TIEHASH
{
my ($class, $defaults) = @_;
my $s = {};
bless $s, $class;
$DEFAULTS{"$s"} = $defaults; # use stringified ref as unique id
return $s;
}
sub FETCH
{
w @_;
# for testing, go straight to the defaults
# my $r = $_[0]->SUPER::EXISTS($_[1]) ? $_[0]->SUPER::FETCH($_[1]) :
# $DEFAULTS{$_[0]}->{$_[1]};
my $r = $DEFAULTS{"$_[0]"}->{$_[1]};
print STDERR "r = $r\n";
return $r;
}
}
my %defaults;
tie %defaults, 'SHash'; # comment out this line, everything works
print "created SHash: " . \%defaults . "\n";
$defaults{h} = { x => 9, y => 10 };
print " defaults{h} = $defaults{h}\n";
my %confighash;
tie %confighash, 'ConfigHash', \%defaults;
print "created ConfigHash: " . \%confighash . " (tied: " .
tied(%confighash) . ")\n";
print "\nINDIRECT:\n";
my $h = $confighash{h}; # extract the defaults element, is a plain hash
print "h->{x} = $h->{x}\n";
print "keys = ", (join ', ', keys %{$h}), "\n";
print "map:\n", map {"\t$_ => $h->{$_}\n"} keys %{$h};
print "\nDIRECT:\n";
print "confighash{h}->{x} = $confighash{h}->{x}\n";
print "keys = ", (join ', ', keys %{$confighash{h}}), "\n";
print "map:\n", map {"\t$_ => $confighash{h}{$_}\n"} keys
%{$confighash{h}};
[Please do not change anything below this line]
-----------------------------------------------------------------
---
Site configuration information for perl 5.00503:
Configured by drow at Sun Apr 30 12:07:23 EDT 2000.
Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration:
Platform:
osname=linux, osvers=2.2.15pre14, archname=i386-linux
uname='linux them 2.2.15pre14 #2 smp mon mar 13 14:29:00 est 2000
i686 unknown '
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef useperlio=undef d_sfio=undef
Compiler:
cc='cc', optimize='-O2 ', gccversion=2.95.2 20000313 (Debian
GNU/Linux)
cppflags='-Dbool=char -DHAS_BOOL -D_REENTRANT -DDEBIAN
-I/usr/local/mnclude'
ccflags ='-Dbool=char -DHAS_BOOL -D_REENTRANT -DDEBIAN
-I/usr/local/include'
stdchar='char', d_stdstdio=undef, usevfork=false
intsize=4, longsize=4, ptrsize=4, doublesize=8
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
alignbytes=4, usemymalloc=n, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lnsl -lndbm -lgdbm -ldbm -ldb -ldl -lm -lc -lposix -lcrypt
libc=, so=so, useshrplib=false, libperl=libperl.a
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'
Locally applied patches:
---
@INC for perl 5.00503:
/usr/lib/perl5/5.005/i386-linux
/usr/lib/perl5/5.005
/usr/local/lib/site_perl/i386-linux
/usr/local/lib/site_perl
/usr/lib/perl5
.
---
Environment for perl 5.00503:
HOME=/home/ben
LANG=C
LANGUAGE (unset)
LC_ALL=en_AU
LC_TIME=en_AU
LD_LIBRARY_PATH=/usr/local/lib
LOGDIR (unset)
PATH=/home/ben/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/sbin:/usr/sbin
PERL_BADLANG (unset)
SHELL=/usr/local/bin/bash
-
[ID 20010329.009] FETCHing "directly" from a complex tied hashevaluates to undef
by Ben Low