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
Special treatment of $a and $b with 'use strict' - tighten up a bit #15797
Comments
From @epaCreated by @epaI understand that the variables $a and $b are handled specially However, if the program does have an explicit 'my $a' or 'my $b', if ($foo) { In the 'else' branch the global $a is being used. But only a moment Is it possible that if 'my $a' is seen in a file, later uses of Global symbol "$a" seen, although "my $a" has been seen elsewhere in this file I think this is about the weakest diagnostic possible to improve the Perl Info
|
From @AbigailOn Fri, Jan 06, 2017 at 09:09:54AM -0800, Ed Avis wrote:
I don't think it's possible to determine this at compile time, other What if the fragment above is as follows: sub something { sub something_else { my $func = @ARGV ? \&something : \&something_else; sort $func 1, 2, 3; Now something() is called from a sort block, but you don't know Abigail |
The RT System itself - Status changed from 'new' to 'open' |
From @epaTo clarify, by 'directly inside a sort {} block' I meant lexically inside it, which is known at compile time. The conditions I suggested for triggering the warning (only when 'my $a' is in the same file, undeclared '$a' is seen, and the code isn't directly inside a sort {} block) are an attempt to improve the current handling of $a and $b under 'use strict' -- which *is* rather a mess -- while trying hard to avoid any false positives. While it is possible to contrive code examples which trigger the warning and yet work as intended, that is the case for any warning. In an ideal world I would like to have some stronger change, such as removing the special treatment for $a and $b altogether under 'use 5.30' or later, unless directly inside a sort {} block. But that would be too big a compatibility break. Hence the suggestion for a warning, which while not perfect, would be an improvement. |
From @AbigailOn Sat, Jan 07, 2017 at 12:27:24PM -0800, Ed Avis via RT wrote:
But doesn't that mean that my example would now trigger a warning?
Abigail |
From dcmertens.perl@gmail.comOn Sun, Jan 8, 2017 at 6:38 AM, Abigail <abigail@abigail.be> wrote:
I think that was Ed's very point. Chances are pretty good that any David -- |
From @iabynOn Sun, Jan 08, 2017 at 07:10:23AM -0500, David Mertens wrote:
Should the following src file emit a warning: sub foo { # ... 1000 lines of code ... sub sort_by_foo { $foo[$a] <=> $foo[$b] } -- |
From @epaDave M, yes that is an example of a false positive. The code relies on the global $a and $b being set when the sort subroutine is called. My personal preference is that the code should give the warning, and the programmer could instead write 'our I will note in passing that the variable names $a and $b are quite commonly used in example code in the perl documentation, as 'ordinary' variable names and not related to sorting. |
From @iabynOn Mon, Jan 09, 2017 at 04:46:53AM -0800, Ed Avis via RT wrote:
I would be opposed. I think my example was representative of many source http://grep.cpan.me/ shows: * more than 1000 distributions with /my\s*\$a\b/ so using $a as a lexical var is very common, and using its presence as -- |
From @epaThe example you gave may be representative - certainly code like that, which uses a named sort comparator and uses global $a,$b, is not unknown. But the proposed warning would not affect all 1000+ distributions that use $a as a lexical variable. Only the case where $a is used as a lexical variable, and also as an undeclared global variable in the same file (outside a sort subroutine) would be affected. That is surely fewer than 1000 though it will likely be nonzero. I agree that lexical $a is common. The motivation for this bug report is to make it work better and be less surprising should the 'my $a' be forgotten. You are probably right that "using its presence as a moderator... isn't going to moderate all that much". Perhaps it cuts the false positives by 50%, which is not great. I wonder whether a whole-file check could look for both $a and $b? If both of them are used without declaration, it's surely deliberate. If just $a by itself pops up in one place, and the code has 'use strict', then it does look odd. (Nobody writes a sort comparator that looks at just one of the two values.) But this would require deferring the warning until end of file, which I don't know if it's possible. |
From @xsawyerxOn 01/09/2017 05:25 PM, Ed Avis via RT wrote:
Honestly, this feels to me like a Perl::Critic policy, rather than a new |
From @epaI agree, it's not pretty. I have contorted it to try to squeeze it into the least intrusive shape while still making some improvement to the current handling of $a and $b. (Do others agree with me that the treatment of $a and $b under 'use strict' is a mess? If the consensus is that there's no problem, there is no need for anything to change. Although I would suggest in that case picking different example variable names in the perl documentation.) Perhaps instead of some long chain of heuristic tests, there should be a simpler but more drastic change which can be opt-in. How about a pragma which just stops the special treatment of $a and $b altogether outside a sort {} block? So if you still want to use them in sort subroutines you declare them with 'our ($a, $b)'. use strict 'vars_ab'; As this is opt-in, the issue of false positives wouldn't arise. |
From @xsawyerxOn 01/10/2017 12:33 PM, Ed Avis via RT wrote:
I try not to form an opinion solely on whether people agree with you or In this case, I think it would be nice to tighten up $a and $b, but it's
That's how I see any Perl::Critic policy for it.
I don't think "strict.pm" would be the best point. You can introduce a |
From @GrinnzOn Tue, Jan 10, 2017 at 7:34 AM, Sawyer X <xsawyerx@gmail.com> wrote:
This is definitely a good idea if someone is up for it. I usually just
I don't know if there is a core Perl::Critic policy for it, but my policy https://metacpan.org/pod/Perl::Critic::Policy::Freenode::DollarAB -Grinnz |
From @epaThanks for the pointers to perlcritic policies. The idea of the bug report is to 'fix the bug' with use strict 'vars', which works excellently but has an annoying blind spot when it comes to $a and $b. Just as use strict 'vars' is too useful and too important to be relegated to a perlcritic policy, I suggest that fixing it for $a and $b is also something that should work out of the box, should the programmer choose it. (I don't know about everyone else, but when hacking on code I do not run perlcritic on it during each edit-run cycle. I rely on Perl's compile-time checking of variable names and other things to give quick feedback of typos or missed declarations. Hence the wish to turn off the special case which doesn't report on undeclared $a and $b.) Since use strict 'vars' is part of the perl core, I think that its variant 'vars_ab' (which is really just "what it should have done all along" in some sense) belongs in core too. This is not to say that anybody must spend their time working on it, but the existence of a separate critic policy is not a good reason to exclude the check from normal compile-time checking. After all, this is not something exotic or weird being proposed, rather it is the current behaviour on $a and $b which is a bit odd and this proposal is to regularize it. |
From zefram@fysh.orgEd Avis via RT wrote:
Shouldn't "what it should have done all along" include $STDIN and the -zefram |
From @rjbs* Ed Avis via RT <perlbug-followup@perl.org> [2017-01-10T06:33:12]
I don't like your proposed solutions to the problem of $a and $b. I should be Your "our" solution says "I do plan to use $a and $b," but says nothing about If I was going to suggest any change -- and I don't think I am -- then I'd say use warnings; I agree that $a and $b's weirdness can lead to bugs. I'm not sure there is a -- |
From @epaZefram asked:
You may be right. To me $STDIN looks more obviously magic. The perl documentation is not full of example code which uses $STDIN as an ordinary variable name. As far as I know $a and $b are the only builtin variables which don't begin with uppercase or punctuation. And they are probably the only ones you would pick unknowingly to use in your program. (It might be a good idea to have a warning on 'my $STDIN', noting that there is a builtin global variable of the same name and you probably want to rename your lexical variable to something else to avoid craziness. But I think that is not the right answer for $a and $b.) |
From @AbigailOn Tue, Jan 10, 2017 at 03:33:12AM -0800, Ed Avis via RT wrote:
A mess? Not really. $a and $b are treated special, and so are a dozen With hindsight, sort would have never used $a, and $b. But if we'd would
If people write pragmas which enforce whatever they think $a and $b How big is the problem you're trying to solve anyway? How wide spread is Abigail |
From @epaI think the use of $a and $b is fairly widespread, perhaps a bit less common than $i and $j or $x and $y. They are natural choices to reach for when you want to pick two arbitrary variables for a loop iterator or whatever. That is just my opinion, but it is backed up by a quick glance through perlfunc. Those code examples were written by experienced Perl developers, who knew about the special sort variables, and they still picked $a or $b a lot of the time as a 'plain vanilla' variable. I prefer to put it this way. 'use strict' is an excellent feature of perl and a big timesaver in the edit-test cycle. Currently $a and $b don't get the benefit of it, which is a pity. They are excluded as a special case. Some way to turn that special case off for new development would regularize the language a little and avoid some 'WTF moments' when first writing and testing code. It is always true that you can write whatever pragma you want and put it on CPAN, but here it's not some wild and wacky feature that is wanted, just to apply the same boring 'use strict' rules that apply to every other lowercase variable name. |
From @xsawyerxOn 01/13/2017 11:31 AM, Ed Avis via RT wrote:
While I understanding the case you're making, I still believe this isn't |
From @epaThanks for your feedback. Is there some other way that this issue could be addressed? For myself, I would be quite happy to say 'no sort "ab"' and have the sort builtin no longer set the $a and $b global variables but always pass them onto the stack instead. Then these two variable names would become entirely ordinary. |
From @xsawyerxOn 01/16/2017 02:54 PM, Ed Avis via RT wrote:
My position is not to introduce a change to the effect you requested. If someone else wants to take a stab at solving this, perhaps further |
Migrated from rt.perl.org#130523 (status was 'open')
Searchable as RT130523$
The text was updated successfully, but these errors were encountered: