logo
Free, unlimited AI code reviews that run on commit
git-lrc git-lrc GitHub Install Now We'd appreciate a star git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt

Perl::Critic::Policy::ValuesAndExpressions::UnexpandedSpecialLiteral - specials like __PACKAGE__ used

Description

       This policy is part of the "Perl::Critic::Pulp" add-on.  It picks up some cases where the special
       literals "__FILE__", "__LINE__" and "__PACKAGE__" (see "Special Literals" in perldata) are used with "=>"
       or as a hash subscript and so don't expand to the respective filename, line number or package name.

           my $seen = { __FILE__ => 1 };          # bad
           return ('At:'.__LINE__ => 123);        # bad
           $obj->{__PACKAGE__}->{myextra} = 123;  # bad

       In each case you get a string "__FILE__", "__LINE__" or "__PACKAGE__", as if

           my $seen = { '__FILE__' => 1 };
           return ('At:__LINE__' => 123);
           $obj->{'__PACKAGE__'}->{'myextra'} = 123;

       where almost certainly it was meant to expand to the filename etc.  On that basis this policy is under
       the "bugs" theme (see "POLICY THEMES" in Perl::Critic).

       Expression forms like

           'MyExtra::'.__PACKAGE__ => 123    # bad

       are still bad because the word immediately to the left of a "=>" is quoted even when that word is part of
       an expression.

       If you really do want a string "__FILE__" etc then the suggestion is to write the quotes, even if you're
       not in the habit of using quotes in hash constructors etc.  It'll pass this policy and make it clear to
       everyone that you really did want the literal string.

       The "__PACKAGE__" literal is new in Perl 5.004 but this policy is applied to all code.  Even if you're
       targeting an earlier Perl extra quotes will make it clear to users of later Perl that a literal string
       "__PACKAGE__" is indeed intended.

   FatCommaAfterNewline
       A "=>" fat comma only quotes when it's on the same line as the preceding bareword, so in the following
       "__PACKAGE__" is not quoted and is therefore not reported by this policy,

           my %hash = (__PACKAGE__   # ok, expands
                       =>
                       'blah');

       Of course whether or not writing this is a good idea is another matter.  It might be a bit subtle to
       depend on the newline.  Probably a plain "," comma would make the intention clearer than "=>".

   ClassData
       A bad "$obj->{__PACKAGE__}" can arise when you're trying to hang extra data on an object using your
       package name to hopefully not clash with the object's native fields.  Unexpanded "__PACKAGE__" like that
       is a mistake you'll probably only make once; after that the irritation of writing extra parens or similar
       will keep it fresh in your mind!

       As usual there's more than one way to do it when associating extra data to an object.  As a crib here are
       some ways,

       Subhash "$obj->{(__PACKAGE__)}->{myfield}"
           The  extra  parens  ensure  expansion, and you get a sub-hash (or sub-array or whatever) to yourself.
           It's easy to delete the single entry from $obj if/when you later want to cleanup.

       Subscript "$obj->{__PACKAGE__,'myfield'}"
           This makes entries in $obj, with the $; separator emulating multidimensional arrays/hashes (see  "$;"
           in perlvar).

       Concated key "$obj->{__PACKAGE__.'--myfield'}"
           Again  entries  in  $obj,  but  key  formed by concatenation and an explicit unlikely separator.  The
           advantage over "," is that the key is a constant (after constant folding), instead  of  a  "join"  on
           every access because $; could change.

       Separate "Tie::HashRef::Weak"
           Use the object as a hash key and the value whatever data you want to associate.  Keeps completely out
           of  the  object's  hair and also works with objects which use a "restricted hash" (see Hash::Util) to
           prevent extra keys.

       Inside-Out "Hash::Util::FieldHash"
           Similar to HashRef with object as key and any value you want as the data outside  the  object,  hence
           the  jargon  "inside  out".  The docs are very hard to follow (as of its version 1.04), especially if
           you're not into OOP, but it's actually fairly simple.

       "Scalar::Footnote"
           Key/value pairs attached to an object using its "magic" list.  Doesn't touch  the  object's  contents
           but separate footnote users must be careful not to let their keys clash.

Home Page

Name

       Perl::Critic::Policy::ValuesAndExpressions::UnexpandedSpecialLiteral - specials like __PACKAGE__ used
       literally

See Also

       Perl::Critic::Pulp, Perl::Critic, "Special Literals" in perldata

See Also