Perl / perl5

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

No warning or error on @$ #15184

Open p5pRT opened 8 years ago

p5pRT commented 8 years ago

Migrated from rt.perl.org#127552 (status was 'open')

Searchable as RT127552$

p5pRT commented 8 years ago

From @epa

Created by @epa

Perl silently accepts an array variable @​$

% perl -E 'use warnings; use strict; say @​$ '

This is unfortunate since it can be a typo for $@​. Please forbid @​$ and @​{$} and %$ and %{$}.

It might be worth going through all the other ASCII punctuation characters X and checking whether @​X and %X should be accepted​:

my $man = `man perlvar`; foreach (33 .. 47\, 58 .. 64) {   my $c = chr $_;   foreach my $p (q{$}\, q{%}\, q{@​}) {   my $v = $p . $c;   if (index($man\, $v) != -1) { say "$v mentioned in perlvar" }   else { eval $v; my $ok = not $@​; say $ok ? "$v accepted" : "$v not accepted" }   } }

I suggest any special punctuation variable not documented should cause an error.

Perl Info ``` Flags: category=core severity=low Site configuration information for perl 5.22.1: Configured by Red Hat, Inc. at Mon Dec 14 11:14:02 UTC 2015. Summary of my perl5 (revision 5 version 22 subversion 1) configuration: Platform: osname=linux, osvers=4.3.0-1.fc24.x86_64, archname=x86_64-linux-thread-multi uname='linux buildvm-04-nfs.phx2.fedoraproject.org 4.3.0-1.fc24.x86_64 #1 smp mon nov 2 16:27:20 utc 2015 x86_64 x86_64 x86_64 gnulinux ' config_args='-des -Doptimize=none -Dccflags=-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -Dldflags=-Wl,-z,relro -Dccdlflags=-Wl,--enable-new-dtags -Wl,-z,relro -Dlddlflags=-shared -Wl,-z,relro -Dshrpdir=/usr/lib64 -DDEBUGGING=-g -Dversion=5.22.1 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib64/perl5 -Dprivlib=/usr/share/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Darchlib=/usr/lib64/perl5 -Dvendorarch=/usr/lib64/perl5/vendor_perl -Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Dusedtrace=/usr/bin/dtrace -Duselargefiles -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dusesitecustomize' hint=recommended, useposix=true, d_sigaction=define useithreads=define, usemultiplicity=define use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fwrapv -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize=' -g', cppflags='-D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fwrapv -fno-strict-aliasing -I/usr/local/include' ccversion='', gccversion='5.3.1 20151207 (Red Hat 5.3.1-2)', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678, doublekind=3 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16, longdblkind=3 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='gcc', ldflags ='-Wl,-z,relro -fstack-protector-strong -L/usr/local/lib' libpth=/usr/local/lib64 /lib64 /usr/lib64 /usr/local/lib /usr/lib /lib/../lib64 /usr/lib/../lib64 /lib libs=-lpthread -lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat perllibs=-lpthread -lresolv -lnsl -ldl -lm -lcrypt -lutil -lc libc=libc-2.22.so, so=so, useshrplib=true, libperl=libperl.so gnulibc_version='2.22' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,--enable-new-dtags -Wl,-z,relro ' cccdlflags='-fPIC', lddlflags='-shared -Wl,-z,relro -L/usr/local/lib -fstack-protector-strong' Locally applied patches: Fedora Patch1: Removes date check, Fedora/RHEL specific Fedora Patch3: support for libdir64 Fedora Patch4: use libresolv instead of libbind Fedora Patch5: USE_MM_LD_RUN_PATH Fedora Patch6: Skip hostname tests, due to builders not being network capable Fedora Patch7: Dont run one io test due to random builder failures Fedora Patch15: Define SONAME for libperl.so Fedora Patch16: Install libperl.so to -Dshrpdir value Fedora Patch22: Document Math::BigInt::CalcEmu requires Math::BigInt (CPAN RT#85015) Fedora Patch26: Make *DBM_File desctructors thread-safe (RT#61912) Fedora Patch27: Make PadlistNAMES() lvalue again (CPAN RT#101063) Fedora Patch28: Make magic vtable writable as a work-around for Coro (CPAN RT#101063) Fedora Patch200: Link XS modules to libperl.so with EU::CBuilder on Linux Fedora Patch201: Link XS modules to libperl.so with EU::MM on Linux @INC for perl 5.22.1: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 . Environment for perl 5.22.1: HOME=/home/eda LANG=en_GB.UTF-8 LANGUAGE (unset) LC_COLLATE=C LC_CTYPE=en_GB.UTF-8 LC_MESSAGES=en_GB.UTF-8 LC_MONETARY=en_GB.UTF-8 LC_NUMERIC=en_GB.UTF-8 LC_TIME=en_GB.UTF-8 LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/eda/bin:/home/eda/bin:/usr/local/bin:/usr/bin:/sbin:/usr/sbin:/sbin:/usr/sbin PERL_BADLANG (unset) SHELL=/bin/bash This email is intended only for the person to whom it is addressed and may contain confidential information. Any retransmission, copying, disclosure or other use of, this information by persons other than the intended recipient is prohibited. If you received this email in error, please contact the sender and delete the material. This email is for information only and is not intended as an offer or solicitation for the purchase or sale of any financial instrument. Wadhwani Asset Management LLP is a Limited Liability Partnership registered in England (OC303168) with registered office at 40 Berkeley Square, 3rd Floor, London, W1J 5AL. It is authorised and regulated by the Financial Conduct Authority. ```
p5pRT commented 8 years ago

From zefram@fysh.org

Ed Avis wrote​:

Perl silently accepts an array variable @​$

$ perl -lwe '@​$ = qw(a b c); print @​$' abc

The array variable works. Making it an error would be an incompatible change. (However\, perlvar(1) does describe punctuation variable names as "reserved".) If it is to be done\, it should probably be done via a deprecation cycle.

-zefram

p5pRT commented 8 years ago

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

p5pRT commented 8 years ago

From @epa

I think a deprecation warning would be fine\, as long as there is a warning.

OTOH\, if it is felt that oddball array variables like @​$ work and should continue to work\, perhaps there should be an explicit statement in perlvar.

-- Ed Avis \eda@​waniasset\.com

p5pRT commented 8 years ago

From @pjcj

On Tue\, Feb 16\, 2016 at 02​:22​:26PM +0000\, Ed Avis wrote​:

OTOH\, if it is felt that oddball array variables like @​$ work and should continue to work\, perhaps there should be an explicit statement in perlvar.

perlvar already states​:

  Perl identifiers that begin with digits\, control characters\, or   punctuation characters are exempt from the effects of the "package"   declaration and are always forced to be in package "main"; they are   also exempt from "strict 'vars'" errors.

Did you miss that\, or do you feel that more is required?

-- Paul Johnson - paul@​pjcj.net http​://www.pjcj.net

p5pRT commented 8 years ago

From @epa

I understand that perl special variables like $! are accessible from all packages and do not need to be declared first. That is not the issue here. The question is which special variables exist in the first place.

I was surprised to find that a special variable @​$ exists\, and produces no error or warning on use\, despite not being mentioned in perlvar. That manual page does say that all variable names consisting of a sequence of digits\, or a single punctuation character\, are reserved for special uses. It then lists the special uses of punctuation variables which currently exist. I had expected that if a punctuation variable was not mentioned in that list\, then it would not exist and attempting to use it would be an error. Instead\, the current implementation is that all possible single-character variables do exist\, and those not mentioned in perlvar have the normal semantics of arrays or hashes. (For scalars\, all single-character variables are mentioned.)

I think that if this is considered the documented behaviour then it is less than ideal because firstly\, it makes typos such as @​$ for $@​ hard to spot\, and secondly it makes it impossible to add new special single-character array or hash variables in future.

But actually\, in my opinion perlvar doesn't make it clear one way or the other. It says the variable names are reserved (which normally indicates that you shouldn't use it for ordinary uses) but when one is not mentioned in the list of special variables\, doesn't say what the semantics of it are.

So there are two options here​:

Either - Disallow the use of single-character punctuation variables which aren't documented. Since there may be current code using them\, it should be done with a deprecation cycle.

Or - Document in perlvar the remaining single-character punctuation variables not currently mentioned\, saying that they have the ordinary array and hash semantics (but of course the names are accessible in all packages and do not need declaring). I think this would be an unhappy choice for the reasons given above. But at least it would clarify things.

p5pRT commented 8 years ago

From @abigail

On Tue\, Feb 16\, 2016 at 07​:40​:33AM -0800\, Ed Avis via RT wrote​:

I understand that perl special variables like $! are accessible from all packages and do not need to be declared first. That is not the issue here. The question is which special variables exist in the first place.

I was surprised to find that a special variable @​$ exists\, and produces no error or warning on use\, despite not being mentioned in perlvar. That manual page does say that all variable names consisting of a sequence of digits\, or a single punctuation character\, are reserved for special uses. It then lists the special uses of punctuation variables which currently exist. I had expected that if a punctuation variable was not mentioned in that list\, then it would not exist and attempting to use it would be an error. Instead\, the current implementation is that all possible single-character variables do exist\, and those not mentioned in perlvar have the normal semantics of arrays or hashes. (For scalars\, all single-character variables are mentioned.)

I find it surprising you expect pervar to enumerate all possible variable names.

I think that if this is considered the documented behaviour then it is less than ideal because firstly\, it makes typos such as @​$ for $@​ hard to spot\, and secondly it makes it impossible to add new special single-character array or hash variables in future.

If "makes typos hard to spot" is a reason to warn\, should perl also warn if one uses two variables with similar names? $l vs $1\, for instance. Or $( and $).

I think scanning for variable names which can be easily mistaken for a typo would be an excellent rule for perlcritic -- the user can then tweak it to her preference depending what she considers an easy typo\, or a sensible name.

But actually\, in my opinion perlvar doesn't make it clear one way or the other. It says the variable names are reserved (which normally indicates that you shouldn't use it for ordinary uses) but when one is not mentioned in the list of special variables\, doesn't say what the semantics of it are.

Perhaps because it doesn't have any semantics? ;-)

But *do* note that the *$ slot *does* have a variable with special meaning​: $$.

So there are two options here​:

Either - Disallow the use of single-character punctuation variables which aren't documented. Since there may be current code using them\, it should be done with a deprecation cycle.

That would lead to forbidding @​$\, but allowing $$.

Or - Document in perlvar the remaining single-character punctuation variables not currently mentioned\, saying that they have the ordinary array and hash semantics (but of course the names are accessible in all packages and do not need declaring). I think this would be an unhappy choice for the reasons given above. But at least it would clarify things.

Other than growing the size of the manual page\, what does listing all unused combinations of $?\, @​?\, %? gives us? Wouldn't a line like

"any variable not listed here does (currently) not have a special meaning"

work as well?

Abigail

p5pRT commented 8 years ago

From @epa

Abigail \<abigail \ abigail.be> writes​:

Either - Disallow the use of single-character punctuation variables which aren't documented. Since there may be current code using them\, it should be done with a deprecation cycle.

That would lead to forbidding @​$\, but allowing $$.

Indeed. $$ is a special variable documented in perlvar. @​$ is not\, although conceivably it might be added in future.

Or - Document in perlvar the remaining single-character punctuation variables not currently mentioned\, saying that they have the ordinary array and hash semantics

Other than growing the size of the manual page\, what does listing all unused combinations of $?\, \ ?\, %? gives us?

I think you misunderstand - documenting them does not have to mean a longhand listing of all the possible single-character names. It would mean an explicit statement of what their semantics are.

However\, giving a documented semantics to the currently unused single- character variables makes it impossible to use them for something else in future without a compatibility break. For example\, sometimes it has been suggested to have a builtin array which corresponds to ($1\, $2\, $3\, ...). This might be given the magic variable name @​/. (The merits of that particular enhancement are not the point here\, nor is the exact choice of name\, it's just an example.)

Currently\, since @​/ is unused and perlvar (in my opinion) doesn't specify what its behaviour is\, it could be used for this new feature or for another. If instead we document the current semantics (which seem somewhat accidental to me) that @​/ behaves as an ordinary array\, then it would not be possible to later change its behaviour without a deprecation cycle.

Therefore\, what I suggest is to document that single-character punctuation variables not currently listed in perlvar are reserved for future expansion\, and to catch any code which is currently using them\, add a deprecation warning. (Potentially this could become a compile-time error at some future point.) This will allow new special variables to be added in future perl versions without any compatibility break.

It will also help to spot typos - I see that you do not see much value in that\, because there would still be plenty of other typos and mistakes which are not detected. I disagree and feel that spotting mistakes such as @​$ for $@​ is useful.

-- Ed Avis \eda@&#8203;waniasset\.com

p5pRT commented 8 years ago

From gm@qwurx.de

From the keyboard of Ed Avis [16.02.16\,16​:38]​:

Abigail \<abigail \ abigail.be> writes​:

Either - Disallow the use of single-character punctuation variables which aren't documented. Since there may be current code using them\, it should be done with a deprecation cycle.

That would lead to forbidding @​$\, but allowing $$.

Indeed. $$ is a special variable documented in perlvar. @​$ is not\, although conceivably it might be added in future.

Or - Document in perlvar the remaining single-character punctuation variables not currently mentioned\, saying that they have the ordinary array and hash semantics

Other than growing the size of the manual page\, what does listing all unused combinations of $?\, \ ?\, %? gives us?

I think you misunderstand - documenting them does not have to mean a longhand listing of all the possible single-character names. It would mean an explicit statement of what their semantics are.

Their semantics are those of ordinary variables and denoted by the sigil. @​~ is an array. If it's empty\, ~@​~ amounts to ~0 which is the max int value on the system (18446744073709551615 here); %; is a hash\, etc.

[...]

Therefore\, what I suggest is to document that single-character punctuation variables not currently listed in perlvar are reserved for future expansion\,

This is exactly what is stated in perlvar​:

  Perl variable names may also be a sequence of digits or a single   punctuation or control character. These names are all reserved for   special uses by Perl; for example\, the all-digits names (...)

Which means (but could be stated explicitly) that those variables may be used for special purposes in the future\, and that usage is on own risk. This is how I have read that bits ever since.

I have never seen use of such variables in devent production code or modules (but they might be used in the Acme namespace); but they are used in perlgolf\, obfuscations and japhs. These are\, while frowned upon by some\, part of the perl culture.

It would be sad if gems like e.g. Erudil's CamelCode would become just ascii art in future versions of perl\, or if Abigail's many japhs would be bereft of their best purpose​: teaching how to read code\, sharpening the eye.

       and to catch any code which is currently using them\, add a

deprecation warning. (Potentially this could become a compile-time error at some future point.) This will allow new special variables to be added in future perl versions without any compatibility break.

Any punctuation variable may be used for any special purpose\, and if it has not been used for that\, no deprecation cycle is necessary. If that breaks existing code\, its their fault\, not perl5porters'. No guarantee is given that any punctuation variable will behave as an ordinary var.

It will also help to spot typos - I see that you do not see much value in that\, because there would still be plenty of other typos and mistakes which are not detected. I disagree and feel that spotting mistakes such as @​$ for $@​ is useful.

I am with Abigail on that​: excellent candidates for perl critic.

0--gg-

-- _($_=" "x(1\<\<5)."?\n".q·/)Oo. G°\ /   /\_¯/(q / ---------------------------- \__(m.====·.(_("always off the crowd"))."· ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

p5pRT commented 8 years ago

From @iabyn

On Tue\, Feb 16\, 2016 at 08​:45​:31PM +0100\, shmem wrote​:

From the keyboard of Ed Avis [16.02.16\,16​:38]​: It will also help to spot typos - I see that you do not see much value in that\, because there would still be plenty of other typos and mistakes which are not detected. I disagree and feel that spotting mistakes such as @​$ for $@​ is useful.

I am with Abigail on that​: excellent candidates for perl critic.

Conversely\, one important use of 'use strict' is to spot typos in variable names.

I think I'm in favour of emitting a warning each time a slot of a punctuation var typeglob is populated which doesn't have a current documented purpose. So use of '@​$' would emit a single compile-time warning along the lines of​:

  '@​$' is a reserved punctuation variable

while of course '$$' wouldn't.

This wouldn't affect golf\, japh's etc unless they are run with -w (which by their very nature\, they probably aren't).

perlvar would make it clear that any undocumented vars will emit this warning\, and that they may acquire a new use in a future release of perl.

-- You're only as old as you look.