Front page | perl.perl5.porters |
Postings from February 2022
The explicit strict hints bits - Can we remove them?
Thread Next
From:
Paul "LeoNerd" Evans
Date:
February 3, 2022 22:23
Subject:
The explicit strict hints bits - Can we remove them?
Message ID:
20220203222313.3dcd1d8c@shy.leonerd.org.uk
Before I get onto my actual point, let me paint a picture that is a
convenient lie, told through rose-tinted spectacles. It is not
completely true, but imagine in some future version of perl where the
`use builtin` feature becomes stable:
.oO(
As well as performing a version check against the version of
the currently-running perl interpreter, the `use VERSION` syntax is
also a convenient shortcut for enabling a number of pragma modules.
A `use VERSION` of any version equal to or greater than:
v5.12 - implies a corresponding use strict
v5.34 - implies a corresponding use warnings
v5.10 - implies a corresponding use feature ':VER'
v5.38 - implies a corresponding use builtin ':VER'
where ":VER" is comprised of the major.minor parts of the
fully-specified VERSION number.
Thus, beginning your file with the line
use v5.40.2;
is equivalent to
use strict;
use warnings;
use feature ':5.40';
use builtin ':5.40';
)Oo.
Unfortunately, this would-be neat and tidy mental model is complicated
by the way that VERSION vs `strict` actually interact in practice.
See, `use v5.12` doesn't do exactly the same as `use strict`. While it
does enable the three strictness checks (refs, subs, vars), it does this
in a way that it remembers it did so in this indirect implied way. This
becomes visible the moment you try to `use VERSION` of some version
number smaller than 5.12 afterwards. At this point it turns off the
strictness flags that were not otherwise enabled by an explicit
`use strict`. For example:
use v5.12;
use strict 'vars'; # technically redundant here
# At this point, all three strictures are turned on
use v5.8;
# At this point, the implicit strict subs and refs are turned off
# but the explicit strict subs is still in effect.
This behaviour is unique to the `strict` pragma, and does not apply to
warnings, feature bundles, or the hypothetical builtin bundles we may
one day add. Even if you explicitly `use feature`, any enabled features
are reset by a subsequent `use v5.8`:
$ perl -e 'use feature "say"; say "Hello"; use v5.0; say "Goodbye"'
String found where operator expected at -e line 1, near "say "Goodbye""
(Do you need to predeclare say?)
((Warnings behave in yet a third way - while a `use VERSION` of any
version number v5.36 will enable `use warnings`, a subsequent version
request for a smaller number will *not* disable it:
$ ./perl -e 'use v5.35.9; use v5.8; my $x = 1 + undef'
Use of uninitialized value in addition (+) at -e line 1.
But this is not the subject of my current point; we should address
that another day))
The reasons I mention all this are two-fold:
1) It is a complicated and weird mental model to try to explain to
people, because it means that `use VERSION` is not *exactly*
equivalent to a shortcut for instead writing out the various
`use` statements on the other pragmata in full. It is harder to
document and explain to users.
2) It consumes an extra three of those most precious PL_hints bits,
of which we are now in a deficit. We have none spare and we'd
really like at least one or two back for some new useful features
we wish to add.
I have had a go at placating the second of these reasons, by trying to
move those hints bits out into their own variable. I have a
work-in-progress branch which mostly does this, though a few tests
still fail:
https://github.com/leonerd/perl5/tree/rehome-explicit-strict-hints
Even if I get the remaining tests to pass however, I'd be reluctant to
suggest merging it because it does not fix the first reason above
(that the model is IMHO-needlessly complicated), and it involves the
addition of another obscurely-used internal variable named
${^EXPLICIT_STRICT} purely for the reason of letting the pureperl
strict.pm gain access to another interpreter-internal variable.
I would much rather just remove the behaviour entirely.
We could get rid of the HINT_EXPLICIT_STRICT_* bits altogether, and
simply state that a `use VERSION` of any number 5.12-or-above is
*exactly* equivalent to `use strict`, or a number 5.10-or-earlier is
exactly `no strict`. This would let us simplify our implementation,
tests, and most importantly user-facing documentation around the `use
VERSION` syntax. And it would gain us three precious hints bits back for
other purposes.
Thoughts, anyone?
--
Paul "LeoNerd" Evans
leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Thread Next
-
The explicit strict hints bits - Can we remove them?
by Paul "LeoNerd" Evans