.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Perl::Critic::Policy::ValuesAndExpressions::UnexpandedSpecialLiteral 3pm" .TH Perl::Critic::Policy::ValuesAndExpressions::UnexpandedSpecialLiteral 3pm "2021-02-28" "perl v5.32.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Perl::Critic::Policy::ValuesAndExpressions::UnexpandedSpecialLiteral \- specials like _\|_PACKAGE_\|_ used literally .SH "DESCRIPTION" .IX Header "DESCRIPTION" This policy is part of the \f(CW\*(C`Perl::Critic::Pulp\*(C'\fR add-on. It picks up some cases where the special literals \f(CW\*(C`_\|_FILE_\|_\*(C'\fR, \&\f(CW\*(C`_\|_LINE_\|_\*(C'\fR and \f(CW\*(C`_\|_PACKAGE_\|_\*(C'\fR (see \*(L"Special Literals\*(R" in perldata) are used with \f(CW\*(C`=>\*(C'\fR or as a hash subscript and so don't expand to the respective filename, line number or package name. .PP .Vb 3 \& my $seen = { _\|_FILE_\|_ => 1 }; # bad \& return (\*(AqAt:\*(Aq._\|_LINE_\|_ => 123); # bad \& $obj\->{_\|_PACKAGE_\|_}\->{myextra} = 123; # bad .Ve .PP In each case you get a string \f(CW"_\|_FILE_\|_"\fR, \f(CW"_\|_LINE_\|_"\fR or \&\f(CW"_\|_PACKAGE_\|_"\fR, as if .PP .Vb 3 \& my $seen = { \*(Aq_\|_FILE_\|_\*(Aq => 1 }; \& return (\*(AqAt:_\|_LINE_\|_\*(Aq => 123); \& $obj\->{\*(Aq_\|_PACKAGE_\|_\*(Aq}\->{\*(Aqmyextra\*(Aq} = 123; .Ve .PP where almost certainly it was meant to expand to the filename etc. On that basis this policy is under the \*(L"bugs\*(R" theme (see \*(L"\s-1POLICY THEMES\*(R"\s0 in Perl::Critic). .PP Expression forms like .PP .Vb 1 \& \*(AqMyExtra::\*(Aq._\|_PACKAGE_\|_ => 123 # bad .Ve .PP are still bad because the word immediately to the left of a \f(CW\*(C`=>\*(C'\fR is quoted even when that word is part of an expression. .PP If you really do want a string \f(CW"_\|_FILE_\|_"\fR 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. .PP The \f(CW\*(C`_\|_PACKAGE_\|_\*(C'\fR 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 \f(CW"_\|_PACKAGE_\|_"\fR is indeed intended. .SS "Fat Comma After Newline" .IX Subsection "Fat Comma After Newline" A \f(CW\*(C`=>\*(C'\fR fat comma only quotes when it's on the same line as the preceding bareword, so in the following \f(CW\*(C`_\|_PACKAGE_\|_\*(C'\fR is not quoted and is therefore not reported by this policy, .PP .Vb 3 \& my %hash = (_\|_PACKAGE_\|_ # ok, expands \& => \& \*(Aqblah\*(Aq); .Ve .PP 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 \f(CW\*(C`,\*(C'\fR comma would make the intention clearer than \f(CW\*(C`=>\*(C'\fR. .SS "Class Data" .IX Subsection "Class Data" A bad \f(CW\*(C`$obj\->{_\|_PACKAGE_\|_}\*(C'\fR 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 \f(CW\*(C`_\|_PACKAGE_\|_\*(C'\fR 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! .PP 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, .ie n .IP "Subhash ""$obj\->{(_\|_PACKAGE_\|_)}\->{myfield}""" 4 .el .IP "Subhash \f(CW$obj\->{(_\|_PACKAGE_\|_)}\->{myfield}\fR" 4 .IX Item "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 \f(CW$obj\fR if/when you later want to cleanup. .ie n .IP "Subscript ""$obj\->{_\|_PACKAGE_\|_,\*(Aqmyfield\*(Aq}""" 4 .el .IP "Subscript \f(CW$obj\->{_\|_PACKAGE_\|_,\*(Aqmyfield\*(Aq}\fR" 4 .IX Item "Subscript $obj->{__PACKAGE__,myfield}" This makes entries in \f(CW$obj\fR, with the \f(CW$;\fR separator emulating multidimensional arrays/hashes (see \*(L"$;\*(R" in perlvar). .ie n .IP "Concated key ""$obj\->{_\|_PACKAGE_\|_.\*(Aq\-\-myfield\*(Aq}""" 4 .el .IP "Concated key \f(CW$obj\->{_\|_PACKAGE_\|_.\*(Aq\-\-myfield\*(Aq}\fR" 4 .IX Item "Concated key $obj->{__PACKAGE__.--myfield}" Again entries in \f(CW$obj\fR, but key formed by concatenation and an explicit unlikely separator. The advantage over \f(CW\*(C`,\*(C'\fR is that the key is a constant (after constant folding), instead of a \f(CW\*(C`join\*(C'\fR on every access because \f(CW$;\fR could change. .ie n .IP "Separate ""Tie::HashRef::Weak""" 4 .el .IP "Separate \f(CWTie::HashRef::Weak\fR" 4 .IX Item "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 \*(L"restricted hash\*(R" (see Hash::Util) to prevent extra keys. .ie n .IP "Inside-Out ""Hash::Util::FieldHash""" 4 .el .IP "Inside-Out \f(CWHash::Util::FieldHash\fR" 4 .IX Item "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 \*(L"inside out\*(R". The docs are very hard to follow (as of its version 1.04), especially if you're not into \s-1OOP,\s0 but it's actually fairly simple. .ie n .IP """Scalar::Footnote""" 4 .el .IP "\f(CWScalar::Footnote\fR" 4 .IX Item "Scalar::Footnote" Key/value pairs attached to an object using its \*(L"magic\*(R" list. Doesn't touch the object's contents but separate footnote users must be careful not to let their keys clash. .SH "SEE ALSO" .IX Header "SEE ALSO" Perl::Critic::Pulp, Perl::Critic, \&\*(L"Special Literals\*(R" in perldata .SH "HOME PAGE" .IX Header "HOME PAGE" http://user42.tuxfamily.org/perl\-critic\-pulp/index.html .SH "COPYRIGHT" .IX Header "COPYRIGHT" Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019, 2021 Kevin Ryde .PP Perl-Critic-Pulp is free software; you can redistribute it and/or modify it under the terms of the \s-1GNU\s0 General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. .PP Perl-Critic-Pulp is distributed in the hope that it will be useful, but \&\s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of \s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE.\s0 See the \s-1GNU\s0 General Public License for more details. .PP You should have received a copy of the \s-1GNU\s0 General Public License along with Perl-Critic-Pulp. If not, see .