Perl::Critic::Policy::ValuesAndExpressions::UnexpandedSpecialLiteral - specials like __PACKAGE__ used literally
This policy is part of the Perl::Critic::Pulp addon. 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.
__FILE__
__LINE__
__PACKAGE__
=>
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__", like
"__FILE__"
"__LINE__"
"__PACKAGE__"
my $seen = { '__FILE__' => 1 }; return ('At:__LINE__' => 123); $obj->{'__PACKAGE__'}->{'myextra'} = 123;
where you almost certainly meant it 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 any => is quoted even when the 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.
$obj->{__PACKAGE__} can arise when you're trying to hang extra data on an object with your package name hopefully not to clash with the object's native fields. An unexpanded __PACKAGE__ 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!
$obj->{__PACKAGE__}
As usual there's more than one way to do it when adding extra data to an object. As a crib here are some ways,
$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.
$obj
$obj->{__PACKAGE__,'myfield'}
This makes entries in $obj, with the $; separator emulating multidimensional arrays/hashes (see "$;" in perlvar).
$;
$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).
,
join
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 works with objects which use a "restricted hash" (see Hash::Util) to prevent extra keys.
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". If you're not into OOP you'll have to read a few times to understand what's going on!
Perl::Critic::Pulp, Perl::Critic, "Special Literals" in perldata
http://www.geocities.com/user42_kevin/perl-critic-pulp/index.html
Copyright 2008, 2009 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/.
To install Perl::Critic::Pulp, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Perl::Critic::Pulp
CPAN shell
perl -MCPAN -e shell install Perl::Critic::Pulp
For more information on module installation, please visit the detailed CPAN module installation guide.