noble (3) Perl::Critic::Policy::Compatibility::ConstantLeadingUnderscore.3pm.gz

Provided by: libperl-critic-pulp-perl_99-1_all bug

NAME

       Perl::Critic::Policy::Compatibility::ConstantLeadingUnderscore - new enough "constant" module for leading
       underscores

DESCRIPTION

       This policy is part of the "Perl::Critic::Pulp" add-on.  It asks that if you have a constant with a
       leading underscore,

           use constant _FOO ...  # leading underscore on name

       then you explicitly declare "use 5.6" or "use constant 1.02", or higher, since "constant.pm" before that
       did not allow leading underscores.

           use constant _FOO => 123;        # bad

           use 5.006;
           use constant _FOO => 123;        # ok

           use constant 1.02;
           use constant _FOO => 123;        # ok

           use constant 1.02 _FOO => 123;   # ok

       The idea is to avoid trouble in code which might run on Perl 5.005, or might in principle still run
       there.  On that basis this policy is under the "compatibility" theme (see "POLICY THEMES" in
       Perl::Critic).

       Asking for the new enough module "use constant 1.02" is suggested, since it's the module feature which is
       required and the code might then still run on Perl 5.005 or earlier if the user has a suitable
       "constant.pm" from CPAN.

   Details
       A version declaration must be before the first leading underscore, so it's checked before the underscore
       is attempted (and would give an error).

           use constant _FOO => 123;        # bad
           use 5.006;

       A "require" for the Perl version is not enough since "use constant" is at "BEGIN" time, before plain
       code.

           require 5.006;                   # doesn't run early enough
           use constant _FOO => 123;        # bad

       But a "require" within a "BEGIN" block is ok (a past style, still found occasionally).

           BEGIN { require 5.006 }
           use constant _FOO => 123;        # ok

           BEGIN {
             require 5.006;
             and_other_setups ...;
           }
           use constant _FOO => 123;        # ok

       Currently "ConstantLeadingUnderscore" pays no attention to any conditionals within the "BEGIN", it
       assumes any "require" there always runs.  It might be tricked by obscure tests but hopefully anything
       like that is rare or does the right thing anyway.

       A quoted version number like

           use constant '1.02';    # no good

       is no good, only a bare number is recognised by the "use" statement as a version check.  A string like
       that in fact goes through to "constant" as a name to define, and which it will reject.

       Leading underscores in a multi-constant hash are not flagged, since new enough "constant.pm" to have
       multi-constants is new enough to have underscores.  See Compatibility::ConstantPragmaHash for multi-
       constants version check.

           use constant { _FOO => 1 };      # not checked

       Leading double-underscore is disallowed by all versions of "constant.pm".  That's not reported by this
       policy since the code won't run at all.

           use constant __FOO => 123;  # not allowed by any constant.pm

   Drawbacks
       Explicitly adding required version numbers in the code can be irritating, especially if other things
       you're doing only run on 5.6 up anyway.  But declaring what code needs is accurate, it allows maybe for
       backports of modules, and explicit versions can be grepped out to create or check Makefile.PL or Build.PL
       prereqs.

       As always, if you don't care about this or if you only ever use Perl 5.6 anyway then you can disable
       "ConstantLeadingUnderscore" from your .perlcriticrc in the usual way (see "CONFIGURATION" in
       Perl::Critic),

           [-Compatibility::ConstantLeadingUnderscore]

OTHER WAYS TO DO IT

       It's easy to write your own constant subr and it can have any name at all (anything acceptable to Perl),
       bypassing the sanity checks or restrictions in "constant.pm".  Only the "()" prototype is a bit obscure.

           sub _FOO () { return 123 }

       The key benefit of subs like this, whether from "constant.pm" or explicitly, is that the value is inlined
       and can be constant-folded in an arithmetic expression etc (see "Constant Functions" in perlsub).

           print 2*_FOO;   # folded to 246 at compile-time

       The purpose of a leading underscore is normally a hint that the sub is meant to be private to the module
       and/or its friends.  If you don't need the constant folding then a "my" scalar is even more private,
       being invisible to anything outside relevant scope,

           my $FOO = 123;         # more private
           # ...
           do_something ($FOO);   # nothing to constant-fold anyway

       The scalar returned from "constant.pm" subs is flagged read-only, which might prevent accidental mis-use
       when passed around.  The "Readonly" module gives the same effect on variables.  If you have
       "Readonly::XS" then it's just a flag too (no performance penalty on using the value).

           use Readonly;
           Readonly::Scalar my $FOO => 123;

SEE ALSO

       Perl::Critic::Pulp, Perl::Critic, Perl::Critic::Policy::Compatibility::ConstantPragmaHash,
       Perl::Critic::Policy::ValuesAndExpressions::ProhibitConstantPragma,
       Perl::Critic::Policy::Modules::RequirePerlVersion

       constant, "Constant Functions" in perlsub

HOME PAGE

       <http://user42.tuxfamily.org/perl-critic-pulp/index.html>

       Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019, 2021 Kevin Ryde

       Perl-Critic-Pulp is free software; you can redistribute it and/or modify it under the terms of the GNU
       General Public License as published by the Free Software Foundation; either version 3, or (at your
       option) any later version.

       Perl-Critic-Pulp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
       even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
       Public License for more details.

       You should have received a copy of the GNU General Public License along with Perl-Critic-Pulp.  If not,
       see <http://www.gnu.org/licenses/>.

perl v5.32.1                                 Perl::Critic::Policy::Compatibility::ConstantLeadingUnderscore(3pm)