develooper Front page | perl.perl5.porters | Postings from April 2013

[perl #117449] GDBM tied hash weirdness; deletion ends 'each' loop

Dominic Hargreaves
April 2, 2013 15:49
[perl #117449] GDBM tied hash weirdness; deletion ends 'each' loop
Message ID:
# New Ticket Created by  Dominic Hargreaves 
# Please include the string:  [perl #117449]
# in the subject line of all future correspondence about this issue. 
# <URL: >

This is a bug report for perl from,
generated with the help of perlbug 1.39 running under perl 5.17.10.

[Please describe your issue here]

The following bug was reported in Debian:

The test program which follows demonstrates that, contrary to all
available documentation (perlfunc and the minimal GDBM_File doc)
the current entry cannot be deleted from a GDBM tied hash:

#! /usr/bin/perl

use GDBM_File;
use warnings;

%iddb = ();
tie %iddb, 'GDBM_File', './weird', &GDBM_WRCREAT|&GDBM_NOLOCK, 0600;

for (1..20) { $iddb{"$_"} = $_; }

print "Before deletion:\n\n";
while (my ($k, $v) = each %iddb) { print "$k:$v\n"; }

while (1) {
    sleep 1;
    $k = each %iddb;
    print "k is $k\n";
    delete $iddb{$k} if $k > 15;

Immediately after the delete, each apparently returns undef.

This behaviour appears to have been the case since roughly forever[1]
but it does go against documentated behaviour, so does appear to be
a genuine bug as far as I can see.

>From perlfunc:

               After "each" has returned all entries from the hash or array,
               the next call to "each" returns the empty list in list context
               and "undef" in scalar context; the next call following that one
               restarts iteration.  Each hash or array has its own internal
               iterator, accessed by "each", "keys", and "values".  The
               iterator is implicitly reset when "each" has reached the end as
               just described; it can be explicitly reset by calling "keys" or
               "values" on the hash or array.  If you add or delete a hash's
               elements while iterating over it, entries may be skipped or
               duplicated--so don't do that.  Exception: In the current
               implementation, it is always safe to delete the item most
               recently returned by "each()", so the following code works

                       while (($key, $value) = each %hash) {
                         print $key, "\n";
                         delete $hash{$key};   # This is safe

[1] <>

[Please do not change anything below this line]
Site configuration information for perl 5.17.10:

Configured by dom at Sun Mar 31 23:53:26 BST 2013.

Summary of my perl5 (revision 5 version 17 subversion 10) configuration:
    osname=linux, osvers=3.2.0-4-686-pae, archname=i686-linux
    uname='linux callisto 3.2.0-4-686-pae #1 smp debian 3.2.39-2 i686 gnulinux '
    config_args='-de -Dprefix=/home/dom/perl5/perlbrew/perls/perl-5.17.10 -Dusedevel'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
    cc='cc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    cppflags='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.7.2', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /lib/i386-linux-gnu /lib/../lib /usr/lib/i386-linux-gnu /usr/lib/../lib /lib /usr/lib
    libs=-lnsl -ldl -lm -lcrypt -lutil -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
    libc=, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector'

Locally applied patches:

@INC for perl 5.17.10:

Environment for perl 5.17.10:
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PERL_BADLANG (unset)
    SHELL=/bin/bash Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About