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

No warning or error on @$ #15184

Open
p5pRT opened this issue Feb 16, 2016 · 10 comments
Open

No warning or error on @$ #15184

p5pRT opened this issue Feb 16, 2016 · 10 comments

Comments

@p5pRT
Copy link

p5pRT commented Feb 16, 2016

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

Searchable as RT127552$

@p5pRT
Copy link
Author

p5pRT commented Feb 16, 2016

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
Copy link
Author

p5pRT commented Feb 16, 2016

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
Copy link
Author

p5pRT commented Feb 16, 2016

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

@p5pRT
Copy link
Author

p5pRT commented Feb 16, 2016

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
Copy link
Author

p5pRT commented Feb 16, 2016

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
Copy link
Author

p5pRT commented Feb 16, 2016

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
Copy link
Author

p5pRT commented Feb 16, 2016

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
Copy link
Author

p5pRT commented Feb 16, 2016

From @epa

Abigail <abigail <at> 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 $?, <at> ?, %? 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@​waniasset.com>

@p5pRT
Copy link
Author

p5pRT commented Feb 16, 2016

From gm@qwurx.de

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

Abigail <abigail <at> 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 $?, <at> ?, %? 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
Copy link
Author

p5pRT commented Apr 5, 2016

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.

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

2 participants