Perl / perl5

šŸŖ The Perl programming language
https://dev.perl.org/perl5/
Other
1.98k stars 560 forks source link

using $hash{value} should emit a warning #10286

Closed p5pRT closed 14 years ago

p5pRT commented 14 years ago

Migrated from rt.perl.org#74108 (status was 'rejected')

Searchable as RT74108$

p5pRT commented 14 years ago

From david+bugs@madore.org

Created by david+bugs@madore.org

When 'value' is a valid bareword\, and '%hash' is a hash\, using '$hash{value}' is interpreted as '$hash{"value"}' and not '$hash{(value)}' as one might expect. E.g.​:

#! /usr/local/bin/perl use strict; use warnings; use constant { value => "answer" }; my %hash; $hash{value} = 42;

This is a terrible cause of possible errors\, because one can have thought safe to replace '"answer"' by 'value' everywhere in a program (or similarly have had '$answer' hold a constant value and thought to replace it by a constant).

Would it be possible to emit a warning?

Perl Info ``` Flags: category=core severity=wishlist Site configuration information for perl 5.10.0: Configured by Debian Project at Fri Aug 28 22:30:10 UTC 2009. Summary of my perl5 (revision 5 version 10 subversion 0) configuration: Platform: osname=linux, osvers=2.6.26-2-amd64, archname=i486-linux-gnu-thread-multi uname='linux puccini 2.6.26-2-amd64 #1 smp fri aug 14 07:12:04 utc 2009 i686 gnulinux ' config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.10 -Darchlib=/usr/lib/perl/5.10 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.10.0 -Dsitearch=/usr/local/lib/perl/5.10.0 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib -Dlibperl=libperl.so.5.10.0 -Dd_dosuid -des' hint=recommended, useposix=true, d_sigaction=define 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='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2 -g', cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include' ccversion='', gccversion='4.3.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 =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib /usr/lib64 libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt perllibs=-ldl -lm -lpthread -lc -lcrypt libc=/lib/libc-2.7.so, so=so, useshrplib=true, libperl=libperl.so.5.10.0 gnulibc_version='2.7' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib' Locally applied patches: @INC for perl 5.10.0: /etc/perl /usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl . Environment for perl 5.10.0: HOME=/home/david LANG=C LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/david/bin/aldebaran.xn--kwg.net:/home/david/bin/i686:/home/david/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/games:/usr/games PERL_BADLANG (unset) SHELL=/bin/zsh ```
p5pRT commented 14 years ago

From zefram@fysh.org

David A. Madore wrote​:

When 'value' is a valid bareword\, and '%hash' is a hash\, using '$hash{value}' is interpreted as '$hash{"value"}' and not '$hash{(value)}' as one might expect. E.g.​:

This is very much intentional. Use of fixed identifier-like strings as hash keys is extremely common\, and worthy of such shorthand. So the interior of $hash{...} is interpreted specially\, just like the left-hand side of =>\, with a bareword being interpreted as a literal string rather than anything else it might have meant.

As you've discovered\, you can override to get standard expression parsing by enclosing the bareword in parens. A prefix +\, as in $hash{+value}\, also achieves this\, and is idiomatic. You can also postfix parens\, as in $hash{value()}\, to force interpretation as a niladic function.

-zefram

p5pRT commented 14 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 14 years ago

@rgs - Status changed from 'open' to 'rejected'

p5pRT commented 14 years ago

From @ap

* David A. Madore \perlbug\-followup@​perl\.org [2010-04-08 10​:25]​:

When 'value' is a valid bareword\, and '%hash' is a hash\, using '$hash{value}' is interpreted as '$hash{"value"}' and not '$hash{(value)}' as one might expect. E.g.​:

#! /usr/local/bin/perl use strict; use warnings; use constant { value => "answer" }; my %hash; $hash{value} = 42;

This is a terrible cause of possible errors\, because one can have thought safe to replace '"answer"' by 'value' everywhere in a program (or similarly have had '$answer' hold a constant value and thought to replace it by a constant).

Would it be possible to emit a warning?

If you resolve it in the other direction\, it might equally be a terrible cause of errors\, if the hash lookup was written first and the constant is only added much later during maintenance (and because constants are subs\, this is package-based\, which means the constant can be in a completely different file).

If you include a warning for this case\, then the same situation would suddenly cause a hash lookup that has always done what it was meant to to throw warnings. Even though the reason for those warnings was the addition of a constant\, ie. a line in the code far away from the hash lookup.

I donā€™t always agree with Abigail when he uses this line\, but Iā€™ll steal it for this case​: this is a job for a lint-type program such as Perl​::Critic.

And itā€™s most certainly not a bug in Perl.

Regards\, -- Aristotle Pagaltzis // \<http​://plasmasturm.org/>