Skip Menu |
Report information
Id: 114786
Status: rejected
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: baxter.brad <bmb [at] Mail.Libs.UGA.EDU>
Cc:
AdminCc:

Operating System: mswin32
PatchStatus: (no value)
Severity: low
Type: core
Perl Version: 5.16.1
Fixed In: (no value)



Subject: EXISTS and SCALAR return values are treated differently
Date: Fri, 7 Sep 2012 12:24:31 -0400
To: perlbug [...] perl.org
From: Brad Baxter <bmb [...] mail.libs.uga.edu>
Download (untitled) / with headers
text/plain 4.4k
This is a bug report for perl from bmb@mail.libs.uga.edu, generated with the help of perlbug 1.39 running under perl 5.16.1. ----------------------------------------------------------------- [Please describe your issue here] Once upon a time, exists() returned the true value that EXISTS() returned, and I found a way to make use of that (beyond true/false). When that changed, I changed my program, so I'm not reporting that as a bug. But it got me looking and I found that scalar %hash returns the true/false value that SCALAR() returns instead of perl's true/false (1/"") which is what EXISTS() returns. This doesn't break any of my code. I'm reporting for two reasons: 1. I think it would be good for perl to be consistent, i.e., if the return value of EXISTS() is changed to 1/"" then so should that of SCALAR() (and others?) 2. The docs might mention that this conversion to 1/"" is happening, so users don't think they might make use of their own return values. use strict; use warnings; sub show { print ">".join(",",@_)."<\n" } tie my %h1, 'P1'; tie my %h2, 'P2'; tie my %h3, 'P3'; show h1 => exists $h1{'hey'}, scalar %h1; show h2 => exists $h2{'hey'}, scalar %h2; show h3 => exists $h3{'hey'}, scalar %h3; package P1; sub TIEHASH { bless {}, shift } sub EXISTS { "Hello World" } sub SCALAR { "Hello World" } package P2; sub TIEHASH { bless {},shift } sub EXISTS { 0 } sub SCALAR { 0 } package P3; sub TIEHASH { bless {},shift } sub EXISTS { undef } sub SCALAR { undef } Output: Show quoted text
>h1,1,Hello World< >h2,,0<
Use of uninitialized value $_[2] in join or string at qt line 4. Show quoted text
>h3,,<
Meaning: P1: exists() returns perl's true values, scalar context, mine P2: exists() returns perl's false values, scalar context, mine P3: ditto [Please do not change anything below this line] ----------------------------------------------------------------- --- Flags: category=core severity=low --- Site configuration information for perl 5.16.1: Configured by strawberry-perl at Thu Aug 9 09:55:53 2012. Summary of my perl5 (revision 5 version 16 subversion 1) configuration: Platform: osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread uname='Win32 strawberry-perl 5.16.1.1 #1 Thu Aug 9 09:54:46 2012 i386' config_args='undef' hint=recommended, useposix=true, d_sigaction=undef useithreads=define, usemultiplicity=define useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=undef, use64bitall=undef, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc', ccflags =' -s -O2 -DWIN32 -DPERL_TEXTMODE_SCRIPTS -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -fno-strict-aliasing -mms-bitfields', optimize='-s -O2', cppflags='-DWIN32' ccversion='', gccversion='4.6.3', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='long long', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='g++', ldflags ='-s -L"C:\strawberry\perl\lib\CORE" -L"C:\strawberry\c\lib"' libpth=C:\strawberry\c\lib C:\strawberry\c\i686-w64-mingw32\lib libs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32 perllibs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32 libc=, so=dll, useshrplib=true, libperl=libperl516.a gnulibc_version='' Dynamic Linking: dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags='-mdll -s -L"C:\strawberry\perl\lib\CORE" -L"C:\strawberry\c\lib"' Locally applied patches: --- @INC for perl 5.16.1: C:/strawberry/perl/site/lib C:/strawberry/perl/vendor/lib C:/strawberry/perl/lib . --- Environment for perl 5.16.1: HOME (unset) LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=C:\windows\SYSTEM32;C:\windows;C:\windows\SYSTEM32\WBEM;C:\windows\SYSTEM32\WINDOWSPOWERSHELL\V1.0\;;C:\Program Files\Bitvise Tunnelier;C:\strawberry\c\bin;C:\strawberry\perl\site\bin;C:\strawberry\perl\bin PERL_BADLANG (unset) SHELL (unset)
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 1.2k
On Fri Sep 07 09:24:56 2012, baxter.brad wrote: Show quoted text
> This is a bug report for perl from bmb@mail.libs.uga.edu, > generated with the help of perlbug 1.39 running under perl 5.16.1. > > > ----------------------------------------------------------------- > [Please describe your issue here] > > Once upon a time, exists() returned the true value that EXISTS() > returned, and I found a way to make use of that (beyond true/false). > > When that changed, I changed my program, so I'm not reporting that > as a bug. But it got me looking and I found that scalar %hash > returns the true/false value that SCALAR() returns instead of perl's > true/false (1/"") which is what EXISTS() returns. > > This doesn't break any of my code. I'm reporting for two reasons: > > 1. I think it would be good for perl to be consistent, i.e., if > the return value of EXISTS() is changed to 1/"" then so should > that of SCALAR() (and others?)
Currently scalar(%untied_hash) returns 0 (not "") for an empty hash and bucket allocation statistics (e.g., "3245/5678"), for non-empty hashes. However, there is talk about making it return a simple boolean, for efficiency. If we don’t make that change, then what you propose would not be appropriate. If we do, then, er, I don’t know. -- Father Chrysostomos
CC: perl5-porters [...] perl.org
Subject: Re: [perl #114786] EXISTS and SCALAR return values are treated differently
Date: Fri, 7 Sep 2012 15:12:50 -0400
To: perlbug-followup [...] perl.org
From: Brad Baxter <bmb [...] mail.libs.uga.edu>
Download (untitled) / with headers
text/plain 757b
On 9/7/12, Father Chrysostomos via RT <perlbug-followup@perl.org> wrote: Show quoted text
> On Fri Sep 07 09:24:56 2012, baxter.brad wrote:
>> 1. I think it would be good for perl to be consistent, i.e., if >> the return value of EXISTS() is changed to 1/"" then so should >> that of SCALAR() (and others?)
> > Currently scalar(%untied_hash) returns 0 (not "") for an empty hash and > bucket allocation statistics (e.g., "3245/5678"), for non-empty hashes. > > However, there is talk about making it return a simple boolean, for > efficiency. > > If we don’t make that change, then what you propose would not be > appropriate. If we do, then, er, I don’t know.
If this is deemed small potatoes enough to be a won't fix, I won't be crushed. :-) Regards, Brad
CC: perl5-porters [...] perl.org
Subject: Re: [perl #114786] EXISTS and SCALAR return values are treated differently
Date: Mon, 10 Sep 2012 09:59:28 -0400
To: perlbug-followup [...] perl.org
From: Brad Baxter <bmb [...] mail.libs.uga.edu>
Download (untitled) / with headers
text/plain 1.5k
On 9/7/12, Father Chrysostomos via RT <perlbug-followup@perl.org> wrote: Show quoted text
> On Fri Sep 07 09:24:56 2012, baxter.brad wrote:
>> >> Once upon a time, exists() returned the true value that EXISTS() >> returned, and I found a way to make use of that (beyond true/false). >> >> When that changed, I changed my program, so I'm not reporting that >> as a bug. But it got me looking and I found that scalar %hash >> returns the true/false value that SCALAR() returns instead of perl's >> true/false (1/"") which is what EXISTS() returns. >> >> This doesn't break any of my code. I'm reporting for two reasons: >> >> 1. I think it would be good for perl to be consistent, i.e., if >> the return value of EXISTS() is changed to 1/"" then so should >> that of SCALAR() (and others?)
> > Currently scalar(%untied_hash) returns 0 (not "") for an empty hash and > bucket allocation statistics (e.g., "3245/5678"), for non-empty hashes. > > However, there is talk about making it return a simple boolean, for > efficiency. > > If we don’t make that change, then what you propose would not be > appropriate. If we do, then, er, I don’t know. >
It occurs to me to wonder then if the answer (for consistency) is to change exists() back to where it returns what EXISTS() returns when you call exists %tied_hash. It strikes me as "unperlish" to have exist() change my explicit return values. If it's a matter of better optimization or fixing something else that was broken, again, I don't have a strong opinion. But if, say, the change (to exists) was inadvertent or casual, then I think changing it back might be the answer. -- Brad
CC: perlbug-followup [...] perl.org, perl5-porters [...] perl.org
Subject: Re: [perl #114786] EXISTS and SCALAR return values are treated differently
Date: Mon, 10 Sep 2012 16:15:54 +0200
To: Brad Baxter <bmb [...] mail.libs.uga.edu>
From: demerphq <demerphq [...] gmail.com>
Download (untitled) / with headers
text/plain 1.9k
On 10 September 2012 15:59, Brad Baxter <bmb@mail.libs.uga.edu> wrote: Show quoted text
> On 9/7/12, Father Chrysostomos via RT <perlbug-followup@perl.org> wrote:
>> On Fri Sep 07 09:24:56 2012, baxter.brad wrote:
>>> >>> Once upon a time, exists() returned the true value that EXISTS() >>> returned, and I found a way to make use of that (beyond true/false). >>> >>> When that changed, I changed my program, so I'm not reporting that >>> as a bug. But it got me looking and I found that scalar %hash >>> returns the true/false value that SCALAR() returns instead of perl's >>> true/false (1/"") which is what EXISTS() returns. >>> >>> This doesn't break any of my code. I'm reporting for two reasons: >>> >>> 1. I think it would be good for perl to be consistent, i.e., if >>> the return value of EXISTS() is changed to 1/"" then so should >>> that of SCALAR() (and others?)
>> >> Currently scalar(%untied_hash) returns 0 (not "") for an empty hash and >> bucket allocation statistics (e.g., "3245/5678"), for non-empty hashes. >> >> However, there is talk about making it return a simple boolean, for >> efficiency. >> >> If we don’t make that change, then what you propose would not be >> appropriate. If we do, then, er, I don’t know. >>
> > It occurs to me to wonder then if the answer (for consistency) is to > change exists() back to where it returns what EXISTS() returns when > you call exists %tied_hash. > > It strikes me as "unperlish" to have exist() change my explicit return > values. If it's a matter of better optimization or fixing something > else that was broken, again, I don't have a strong opinion. But if, > say, the change (to exists) was inadvertent or casual, then I think > changing it back might be the answer.
I have code to add a way to get detailed hash utilization stats. At that point there is no need at all for the behavior of keys in scalar context. And at that point there need be no difference. Yves -- perl -Mre=debug -e "/just|another|perl|hacker/"
CC: Brad Baxter <bmb [...] mail.libs.uga.edu>, perlbug-followup [...] perl.org, perl5-porters [...] perl.org
Subject: Re: [perl #114786] EXISTS and SCALAR return values are treated differently
Date: Mon, 10 Sep 2012 11:38:03 -0400
To: demerphq <demerphq [...] gmail.com>
From: Ricardo Signes <perl.p5p [...] rjbs.manxome.org>
Download (untitled) / with headers
text/plain 150b
* demerphq <demerphq@gmail.com> [2012-09-10T10:15:54] Show quoted text
> I have code to add a way to get detailed hash utilization stats.
Where's it at? :) -- rjbs
Download signature.asc
application/pgp-signature 490b

Message body not shown because it is not plain text.

CC: Brad Baxter <bmb [...] mail.libs.uga.edu>, perlbug-followup [...] perl.org, perl5-porters [...] perl.org
Subject: Re: [perl #114786] EXISTS and SCALAR return values are treated differently
Date: Mon, 10 Sep 2012 17:50:50 +0200
To: Ricardo Signes <perl.p5p [...] rjbs.manxome.org>
From: demerphq <demerphq [...] gmail.com>
Download (untitled) / with headers
text/plain 5.7k
On 10 September 2012 17:38, Ricardo Signes <perl.p5p@rjbs.manxome.org> wrote: Show quoted text
> * demerphq <demerphq@gmail.com> [2012-09-10T10:15:54]
>> I have code to add a way to get detailed hash utilization stats.
> > Where's it at? :)
commit 064454668c9c3bb81c99f1b23776d9ada6305c86 Author: Yves Orton <demerphq@gmail.com> Date: Mon Sep 10 17:39:13 2012 +0200 add routines for introspecting hash utilization to the Internals namespace my ($keys,$buckets,$used_buckets, $max_used_bucket_chain, $min_used_bucket_chain, $average_length_of_used_bucket_chain, $stddev_of_used_bucket_chain, $bucket_length_counts_array_ref)= Internals::bucket_info($hashref); my ($key_info_array)= Internals::bucket_array($hashref); bucket_array() returns an AoA of keys per bucket in the order they are stored in the buckets. It is "useful" for introspecting the actual bucket orders. bucket_into() returns a detailed summary of the utilization and statistics of the hash. Work In Progress. ---- Here is an example of usage. Im not so happy with the interface, so dont consider this "done" yet. Its close, but not time to stick the fork in. $ time ./perl -Ilib -MData::Dumper -le'$x="AAAAAA"; for my $i (1 .. 4000000) { $foo{$x++}=$i; if ($i % 100000==0) { my (@b)= Internals::bucket_info(\%foo); my $array= pop @b; print join("\t", @b, @$array); }}' 100000 131072 69928 7 1 1.43004232925295 0.478145622278707 61139 46584 17826 4488 878 126 24 2 200000 262144 139828 7 1 1.43032868953285 0.477016492357962 122315 93104 35667 9000 1758 267 29 3 300000 524288 228340 7 1 1.3138302531313 0.340794096788173 295946 169119 48474 9231 1354 150 10 2 400000 524288 279673 8 1 1.43024174661122 0.478699414514492 244615 186381 71068 18133 3454 564 65 6 2 500000 524288 322100 9 1 1.55231294628997 0.625599276172039 202188 192451 91808 29351 6870 1361 225 29 3 2 600000 1048576 456848 7 1 1.31334710888523 0.340777971379674 591726 338600 96719 18531 2657 307 32 2 700000 1048576 510144 7 1 1.37216158574834 0.410517206859561 538431 358471 119553 26828 4613 590 86 3 800000 1048576 558711 8 1 1.4318672802218 0.479919271005158 489864 371668 142526 36160 7152 1049 146 9 1 900000 1048576 602988 8 1 1.49256701625903 0.553032042705448 445587 379999 163662 46950 10363 1742 242 27 3 1000000 1048576 643232 8 1 1.55464902243669 0.628350233762166 405343 383612 183589 58669 14159 2715 432 48 8 1100000 2097152 854541 8 1 1.28724075263797 0.311237462097474 1242611 648984 170663 30421 3991 435 43 2 2 1200000 2097152 912367 8 1 1.31526019682869 0.343990700897308 1184785 675370 193295 37556 5437 637 67 3 2 1300000 2097152 967153 8 1 1.34415133903322 0.377825700025547 1129999 697298 216155 45538 7162 883 106 9 2 1400000 2097152 1019822 9 1 1.37278858467458 0.411428642896101 1077330 716316 238929 54060 9136 1204 160 15 1 1 1500000 2097152 1069193 9 1 1.40292725448072 0.447617145154267 1027959 730867 261533 63316 11534 1704 215 20 3 1 1600000 2097152 1116974 9 1 1.43244157876549 0.483058221565786 980178 743570 283514 73088 14248 2221 295 34 3 1 1700000 2097152 1162056 10 1 1.46292433411126 0.520182015333899 935096 752844 305054 83463 17347 2874 423 47 3 0 1 1800000 2097152 1205414 10 1 1.49326289556949 0.556710630517747 891738 760023 326073 94427 20634 3609 579 60 7 1 1 1900000 2097152 1246923 10 1 1.5237508651296 0.593128329699392 850229 764996 346628 105659 24359 4465 721 79 14 1 1 2000000 2097152 1286282 10 1 1.55486899451287 0.631244168055112 810870 767827 365900 117606 28383 5544 880 119 18 4 1 2100000 4194304 1648183 7 1 1.27413036052429 0.296214827418435 2546118 1267020 319066 54389 6923 725 56 4 2200000 4194304 1707731 7 1 1.28825909935464 0.31267569741358 2486570 1295826 341804 60920 8185 914 78 4 2300000 4194304 1765960 7 1 1.30240775555505 0.329052845038042 2428341 1322707 364520 68001 9519 1108 101 4 2400000 4194304 1821333 7 1 1.31771620016768 0.347520810086662 2372968 1345542 387271 75843 11149 1383 139 6 2500000 4194304 1877000 8 1 1.3319126265317 0.364275137810736 2317301 1368866 409950 83511 12856 1638 167 11 1 2600000 4194304 1930670 8 1 1.34668275779911 0.381505295945099 2263631 1389068 433115 91659 14655 1948 211 13 1 2700000 4194304 1983092 8 1 1.36151020729245 0.399011463063935 2211209 1407694 455959 100232 16644 2283 261 17 2 2800000 4194304 2034654 8 1 1.37615535614409 0.416463439384064 2159647 1425319 478492 109062 18752 2696 310 21 2 2900000 4194304 2085515 8 1 1.39054382250907 0.433560494517518 2108786 1442036 500911 118107 20925 3132 370 31 3 3000000 4194304 2129955 8 1 1.40848046085481 0.456852195203926 2064346 1450309 522539 128693 24121 3764 476 50 3 3100000 4194304 2175130 8 1 1.42520217182421 0.47851726901148 2019171 1459922 543818 138972 27310 4434 608 60 6 3200000 4194304 2221768 9 1 1.44029439617458 0.497428143821205 1972535 1471555 565157 148911 30244 5083 726 86 5 1 3300000 4194304 2267668 9 1 1.45523947950053 0.515784373042378 1926635 1482201 586291 159327 33102 5782 848 107 9 1 3400000 4194304 2312948 9 1 1.46998549037851 0.533652867558223 1881355 1492008 607551 169473 36375 6431 968 129 12 1 3500000 4194304 2357461 9 1 1.484648102344 0.55181639984542 1836842 1501240 627995 180080 39672 7192 1110 156 14 2 3600000 4194304 2400301 9 1 1.49981189859105 0.570243134120352 1794002 1507983 648774 190876 43206 7977 1285 180 18 2 3700000 4194304 2442319 9 1 1.51495361580531 0.588539671320727 1751984 1513895 668937 202167 46795 8855 1439 210 18 3 3800000 4194304 2483668 9 1 1.52999515233115 0.606765647075871 1710635 1519037 689048 213292 50648 9756 1619 244 19 5 3900000 4194304 2523882 9 1 1.54523864427893 0.625342740790641 1670421 1522917 708722 224675 54671 10796 1800 264 31 6 4000000 4194304 2563262 9 1 1.56051156690186 0.644061251792658 1631041 1525867 728177 236138 58813 11878 2048 299 36 6 real 0m12.096s user 0m11.893s sys 0m0.160s -- perl -Mre=debug -e "/just|another|perl|hacker/"
Subject: Re: [perl #114786] EXISTS and SCALAR return values are treated differently
From: Zefram <zefram [...] fysh.org>
Date: Fri, 15 Dec 2017 05:33:28 +0000
To: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 441b
The behaviour is not a bug, and indeed it's a general feature of the tied interfaces that the tied methods only get to return the kind of thing that the vanilla internals could have returned. That means EXISTS only gets to return a truth value. SCALAR gets to return a general scalar, because the vanilla behaviour of a hash in scalar context returns something with more content than a truth value. This ticket should be closed. -zefram


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org