Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.85k stars 527 forks source link

Is ||= supposed work like this ? #6440

Closed p5pRT closed 20 years ago

p5pRT commented 21 years ago

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

Searchable as RT21946$

p5pRT commented 21 years ago

From balazs@sportsline.com

Created by balazs@dwwc.com

Isn't

perl -e 'sub foo{delete $a->{x}; 2}; $a->{x}||=foo(); print $a->{x}'

and

perl -e 'sub foo{delete $a->{x}; 2}; $a->{x}=foo(); print $a->{x}'

supposed to print the same thing ? I understand that global variables are evil\, but fwiw my intuition says that they should both print 2.

Thanks\,

Balazs

Perl Info ``` Flags: category=core severity=medium Site configuration information for perl v5.6.0: Configured by bhcompile at Thu Aug 9 22:47:55 EDT 2001. Summary of my perl5 (revision 5.0 version 6 subversion 0) configuration: Platform: osname=linux, osvers=2.4.6-3.1enterprise, archname=i386-linux uname='linux stripples.devel.redhat.com 2.4.6-3.1enterprise #1 smp tue jul 24 14:03:17 edt 2001 i686 unknown ' config_args='-des -Doptimize=-O2 -march=i386 -mcpu=i686 -Dcc=gcc -Dcccdlflags=-fPIC -Dinstallprefix=/usr -Dprefix=/usr -Darchname=i386-linux -Dd_dosuid -Dd_semctl_semun -Di_db -Di_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Uuselargefiles' hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef useperlio=undef d_sfio=undef uselargefiles=undef use64bitint=undef use64bitall=undef uselongdouble=undef usesocks=undef Compiler: cc='gcc', optimize='-O2 -march=i386 -mcpu=i686', gccversion=2.96 20000731 (Red Hat Linux 7.1 2.96-96) cppflags='-fno-strict-aliasing -I/usr/local/include' ccflags ='-fno-strict-aliasing -I/usr/local/include' stdchar='char', d_stdstdio=define, usevfork=false intsize=4, longsize=4, ptrsize=4, doublesize=8 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=4 alignbytes=4, usemymalloc=n, prototype=define Linker and Libraries: ld='gcc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -ldl -lm -lc -lcrypt libc=/lib/libc-2.2.4.so, 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 v5.6.0: /net/balazs/fsrc/media/appslib /net/balazs/fsrc/core/lib /net/balazs/fsrc/baseball/lib /net/balazs/fsrc/golf/appslib /net/balazs/fsrc/baseball/appslib /net/balazs/fsrc/media/appslib /net/balazs/fsrc/core/lib /net/balazs/fsrc/media/appslib /net/balazs/fsrc/core/lib /net/balazs/fsrc/baseball/lib /net/balazs/fsrc/media/appslib /net/balazs/fsrc/core/lib /net/balazs/fsrc/baseball/lib /usr/lib/perl5/5.6.0/i386-linux /usr/lib/perl5/5.6.0 /usr/lib/perl5/site_perl/5.6.0/i386-linux /usr/lib/perl5/site_perl/5.6.0 /usr/lib/perl5/site_perl . Environment for perl v5.6.0: HOME=/net/balazs LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/net/balazs/fsrc/core/bin:/net/balazs/fsrc/media/bin:/net/balazs/fsrc/baseball/bin:/net/sysadm/bin:/net/sysadm:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/net/balazs/bin:/net/balazs/src/football/bin:/net/balazs/bin PERL5LIB=/net/balazs/fsrc/media/appslib:/net/balazs/fsrc/core/lib:/net/balazs/fsrc/baseball/lib:/net/balazs/fsrc/golf/appslib:/net/balazs/fsrc/baseball/appslib:/net/balazs/fsrc/media/appslib:/net/balazs/fsrc/core/lib:/net/balazs/fsrc/media/appslib:/net/balazs/fsrc/core/lib:/net/balazs/fsrc/baseball/lib:/net/balazs/fsrc/media/appslib:/net/balazs/fsrc/core/lib:/net/balazs/fsrc/baseball/lib: PERL_BADLANG (unset) SHELL=/bin/bash ```
p5pRT commented 20 years ago

From alex@rcon.org

This isn't strictly speaking a bug\, as you are relying on execution order of the components of the assignment / if-assignment which perl does not specify. It so happens that in the '||=' case perl creates the left hand side first\, then calls the right hand side\, which then removes the 'x' key from the hash\, it doesn't delete the bit of memory which will hold the result of the rhs\, it just happens that nothing points to it\, so later\, the print doesn't\, as it were.

With the '='\, it runs right\, then left\, thus creating somewhere for the result.

The same happens with lexicals;

perl -le 'my $m; sub foo {delete $_[0]->{x}; 2}; $m->{x} ||= foo($m); print $m->{x}'

p5pRT commented 20 years ago

alex@rcon.org - Status changed from 'new' to 'resolved'