Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scalar( %tied_hash) #6051

Closed
p5pRT opened this issue Nov 1, 2002 · 8 comments
Closed

scalar( %tied_hash) #6051

p5pRT opened this issue Nov 1, 2002 · 8 comments

Comments

@p5pRT
Copy link

p5pRT commented Nov 1, 2002

Migrated from rt.perl.org#18186 (status was 'resolved')

Searchable as RT18186$

@p5pRT
Copy link
Author

p5pRT commented Nov 1, 2002

From rir@attbi.com

Created by rir@attbi.com

A snippet like "if ( %tied_hash) { impossible_call() }", is
broken because a tied hash always returns false.

Perl Info

Flags:
    category=core
    severity=high

Site configuration information for perl v5.6.1:

Configured by bod at Fri Jan 11 04:14:18 EST 2002.

Summary of my perl5 (revision 5.0 version 6 subversion 1) configuration:
  Platform:
    osname=linux, osvers=2.4.13, archname=i386-linux
    uname='linux duende 2.4.13 #1 wed oct 31 19:18:07 est 2001 i686 unknown '
    config_args='-Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i386-linux -Dprefix=/usr -Dprivlib=/usr/share/perl/5.6.1 -Darchlib=/usr/lib/perl/5.6.1 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.6.1 -Dsitearch=/usr/local/lib/perl/5.6.1 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Duseshrplib -Dlibperl=libperl.so.5.6.1 -Dd_dosuid -des'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    useperlio=undef d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
  Compiler:
    cc='cc', ccflags ='-DDEBIAN -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-DDEBIAN -fno-strict-aliasing -I/usr/local/include'
    ccversion='', gccversion='2.95.4  (Debian prerelease)', 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, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lgdbm -ldb -ldl -lm -lc -lcrypt
    perllibs=-ldl -lm -lc -lcrypt
    libc=/lib/libc-2.2.4.so, so=so, useshrplib=true, libperl=libperl.so.5.6.1
  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 v5.6.1:
    /home/rir/Rbks2/Lib/
    /home/rir/Rbks2/Lib/Tk
    /home/rir/Rbks2/Lib/Auto
    /usr/local/lib/perl/5.6.1
    /usr/local/share/perl/5.6.1
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.6.1
    /usr/share/perl/5.6.1
    /usr/local/lib/site_perl
    .


Environment for perl v5.6.1:
    HOME=/home/rir
    LANG=C
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/rir/Bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/sather/sather/bin
    PERL5LIB=/home/rir/Rbks2/Lib/:/home/rir/Rbks2/Lib/Tk:/home/rir/Rbks2/Lib/Auto
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Nov 1, 2002

From @ysth

On 1 Nov 2002 00​:28​:46 -0000, rir@​attbi.com wrote​:

A snippet like "if ( %tied_hash) { impossible_call() }", is
broken because a tied hash always returns false.

I also reported this a little while ago. It is difficult to fix.
It would be easy enough to make scalar(%tiedhash) return 0
if empty, and "1/1" or some such if not empty, but to test
for emptiness you need to call FIRSTKEY, and that means that​:

print each(%stdhash),scalar(%stdhash),each(%stdhash)

won't work like​:

print each(%tiedhash),scalar(%tiedhash),each(%tiedhash)

Anyone have any good answers?

The workaround is to say​:
if (keys %tied_hash) { }

@p5pRT
Copy link
Author

p5pRT commented Nov 1, 2002

From @mjdominus

I also reported this a little while ago. It is difficult to fix.
It would be easy enough to make scalar(%tiedhash) return 0
if empty, and "1/1" or some such if not empty, but to test
for emptiness you need to call FIRSTKEY, and that means that​:

print each(%stdhash),scalar(%stdhash),each(%stdhash)

won't work like​:

print each(%tiedhash),scalar(%tiedhash),each(%tiedhash)

Anyone have any good answers?

Couldn't pp_rv2hv be fixed so that it would check for a HASHSIZE
method in the tied package, and call it if so?

HASHSIZE could also be called by keys() in scalar context, which would
give a tied hash class an opportunity to efficiently report its size
without Perl having to iterate over all the keys. The iteration could
be used as a fallback if HASHSIZE was not defined.

@p5pRT
Copy link
Author

p5pRT commented Nov 1, 2002

From rick.delaney@rogers.com

Mark Jason Dominus <mjd@​plover.com> writes​:

Couldn't pp_rv2hv be fixed so that it would check for a HASHSIZE
method in the tied package, and call it if so?

Sounds good to me.

HASHSIZE could also be called by keys() in scalar context, which would
give a tied hash class an opportunity to efficiently report its size
without Perl having to iterate over all the keys. The iteration could
be used as a fallback if HASHSIZE was not defined.

This may be of some use, if it wasn't rejected because it is unwanted​:

http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2001-04/msg00613.html

--
Rick Delaney
rick.delaney@​rogers.com

@p5pRT
Copy link
Author

p5pRT commented Nov 1, 2002

From @ysth

On Fri, 01 Nov 2002 00​:02​:50 -0500, mjd@​plover.com wrote​:

I also reported this a little while ago. It is difficult to fix.
It would be easy enough to make scalar(%tiedhash) return 0
if empty, and "1/1" or some such if not empty, but to test
for emptiness you need to call FIRSTKEY, and that means that​:

print each(%stdhash),scalar(%stdhash),each(%stdhash)

won't work like​:

print each(%tiedhash),scalar(%tiedhash),each(%tiedhash)

Anyone have any good answers?

Couldn't pp_rv2hv be fixed so that it would check for a HASHSIZE
method in the tied package, and call it if so?

and pp_padhv

HASHSIZE could also be called by keys() in scalar context, which would
give a tied hash class an opportunity to efficiently report its size
without Perl having to iterate over all the keys. The iteration could
be used as a fallback if HASHSIZE was not defined.

Good! But scalar keys %hash *does* reset the iterator for a standard
hash. So would HASHSIZE take a parameter to determine if it was
called for scalar(%hash) or scalar(keys(%hash))?

Also, for scalar(%hash), all we really want to do is tell if it is
empty or not, so reporting the size may not be ideally efficient.

@p5pRT
Copy link
Author

p5pRT commented Nov 1, 2002

From rir@attbi.com

On Fri, Nov 01, 2002 at 05​:46​:52AM -0000, Yitzchak Scott-Thoennes wrote​:

On Fri, 01 Nov 2002 00​:02​:50 -0500, mjd@​plover.com wrote​:

I also reported this a little while ago. It is difficult to fix.
It would be easy enough to make scalar(%tiedhash) return 0
if empty, and "1/1" or some such if not empty, but to test
for emptiness you need to call FIRSTKEY, and that means that​:

Thanks all.

I'm not pretending to teach anyone here, rather I'm trying to
expose my limited understanding.

If a tied hash can determine its context the problem is at least
solveable. It seems like​: list context, scalar context and being
called from the hash builtins "each", "keys" and "values" are the
info needed.

Have a tied-hash by default return 0 in scalar context, preserving
existing code. Create a new tied function that would override
the default.

Also, for scalar(%hash), all we really want to do is tell if it is
empty or not, so reporting the size may not be ideally efficient.

This is my thinking also. But HASHSIZE might mask the possible
bug outlined below. If not it is an optimization only for the
builtin "keys".

HASHSIZE is a different issue though, I was thinking of something like
BUCKETS or SCALARVALUE.

HASHSIZE does evoke the idea of LISTVALUE which would yield the
appropriate list without going through the intermediate
FIRSTKEY, NEXTKEY steps. Whether this is only an optimization depends
on the behaviour of​:

  foreach ( keys %hash) {
  ($some, @​list) = %hash; # Effect loop? tied vs. ordinary
  }

I have not written such code so I don't know whether
this is another tied hash bug. I assume it is.

SCALARVALUE and LISTVALUE _might_ be merged into one
function (HASH, HASHVALUE, SELF). I don't see it as
important. I don't know the implementation or
performance costs.

--
rir Live the dream.

@p5pRT
Copy link
Author

p5pRT commented Mar 29, 2010

From @iabyn

From 5.9.1 onwards, %tied_hash in boolean context checks the SCALAR()
method, with a fallback to calling FIRSTKEY(). So I'm marking this as
resolved.

@p5pRT
Copy link
Author

p5pRT commented Mar 29, 2010

@iabyn - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant