develooper 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




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About