Open p5pRT opened 8 years ago
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.
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
The RT System itself - Status changed from 'new' to 'open'
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
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
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.
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
Abigail \<abigail \
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@​waniasset\.com
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}
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.
Migrated from rt.perl.org#127552 (status was 'open')
Searchable as RT127552$