Code Monkey home page Code Monkey logo

perl-critic-community's Introduction

NAME

Perl::Critic::Community - Community-inspired Perl::Critic policies

SYNOPSIS

$ perlcritic --theme community script.pl
$ perlcritic --theme community lib/

# .perlcriticrc
theme = community
severity = 1

DESCRIPTION

A set of Perl::Critic policies to enforce the practices generally recommended by subsets of the Perl community, particularly on IRC. Formerly known as Perl::Critic::Freenode. Because this policy "theme" is designed to be used with zero configuration on the command line, some duplication will occur if it is used in combination with core Perl::Critic policies.

AFFILIATION

This module has no functionality, but instead contains documentation for this distribution and acts as a means of pulling other modules into a bundle. All of the Policy modules contained herein will have an "AFFILIATION" section announcing their participation in this grouping.

POLICIES

Perl::Critic::Policy::Community::AmpersandSubCalls

Don't use & to call subroutines

Perl::Critic::Policy::Community::ArrayAssignAref

Don't assign an anonymous arrayref to an array

Perl::Critic::Policy::Community::BarewordFilehandles

Don't use bareword filehandles other than built-ins

Perl::Critic::Policy::Community::ConditionalDeclarations

Don't declare variables conditionally

Perl::Critic::Policy::Community::ConditionalImplicitReturn

Don't end a subroutine with a conditional block

Perl::Critic::Policy::Community::DeprecatedFeatures

Avoid features that have been deprecated or removed from Perl

Perl::Critic::Policy::Community::DiscouragedModules

Various modules discouraged from use

Perl::Critic::Policy::Community::DollarAB

Don't use $a or $b as variable names outside sort()

Perl::Critic::Policy::Community::Each

Don't use each() to iterate through a hash

Perl::Critic::Policy::Community::EmptyReturn

Don't use return with no arguments

Perl::Critic::Policy::Community::IndirectObjectNotation

Don't call methods indirectly

Perl::Critic::Policy::Community::LexicalForeachIterator

Don't use undeclared foreach loop iterators

Perl::Critic::Policy::Community::LoopOnHash

Don't loop over hashes

Perl::Critic::Policy::Community::ModPerl

Don't use mod_perl to write web applications

Perl::Critic::Policy::Community::MultidimensionalArrayEmulation

Don't use multidimensional array emulation

Perl::Critic::Policy::Community::OpenArgs

Always use the three-argument form of open()

Perl::Critic::Policy::Community::OverloadOptions

Don't use overload without specifying a bool overload and enabling fallback

Perl::Critic::Policy::Community::PackageMatchesFilename

Module files should declare a package matching the filename

Perl::Critic::Policy::Community::POSIXImports

Don't use POSIX without specifying an import list

Perl::Critic::Policy::Community::PreferredAlternatives

Various modules with preferred alternatives

Perl::Critic::Policy::Community::Prototypes

Don't use function prototypes

Perl::Critic::Policy::Community::StrictWarnings

Always use strict and warnings, or a module that imports these

Perl::Critic::Policy::Community::Threads

Interpreter-based threads are officially discouraged

Perl::Critic::Policy::Community::Wantarray

Don't write context-sensitive functions using wantarray()

Perl::Critic::Policy::Community::WarningsSwitch

Scripts should not use the -w switch on the shebang line

Perl::Critic::Policy::Community::WhileDiamondDefaultAssignment

Don't use while with implicit assignment to $_

CONFIGURATION AND ENVIRONMENT

All policies included are in the "community" theme. See the Perl::Critic documentation for how to make use of this.

AUTHOR

Dan Book, [email protected]

CONTRIBUTORS

Graham Knop (haarg)
H.Merijn Brand (Tux)
John SJ Anderson (genehack)
Matt S Trout (mst)
William Taylor (willt)

COPYRIGHT AND LICENSE

Copyright 2015, Dan Book.

This library is free software; you may redistribute it and/or modify it under the terms of the Artistic License version 2.0.

SEE ALSO

Perl::Critic

perl-critic-community's People

Contributors

amorymeltzer avatar drhyde avatar grinnz avatar haarg avatar karenetheridge avatar marlencrabapple avatar simcop2387 avatar willt avatar xenu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

perl-critic-community's Issues

Wording for discouraged modules

Using 'sane' to refer to other event loops in the AE entry is fine, using it to refer to people in the JSON::XS entry less so. "more collaborative maintainer" would be clearer anyway.

Freenode::DollarAB - false negative

$ cat test.pl
#!perl

use strict;
use warnings;

our $VERSION = "0.00";

my @c;
my %row = map { $_ => 1 } 0..10;
push @c, [ @row{sort { $a <=> $b } keys %row } ];
$ perlcritic -1 test.pl
test.pl#10.24:  [4 - Freenode::DollarAB]        Using $a or $b outside sort()   :$a <=> $b
test.pl#10.31:  [4 - Freenode::DollarAB]        Using $a or $b outside sort()   :$a <=> $b

additional modules for DiscouragedModules / PreferredAlternatives

  • File::HomeDir: has many features that usually aren't needed (and has additional prereqs for darwin, which can cause issues in a cpanfile.snapshot when some team members are on darwin and others aren't): for the normal homedir case, simply use this (simplifying if windows or older perls aren't supported):
    my $homedir = $^O eq 'MSWin32' && "$]" < 5.016
      ? $ENV{HOME} || $ENV{USERPROFILE}
      : (<~>)[0];
  • Test::Requires -> Test::Needs: (quoted from docs) "Test::Requires will act as a "use" statement (despite its name), calling the import sub. Under "RELEASE_TESTING", it will BAIL_OUT if a module fails to load rather than using a normal test fail. It also doesn't distinguish between missing modules and broken modules."

  • FindBin -> Dir::Self - I'm sure there was an article somewhere talking about what's wrong with FindBin, but I haven't been able to find it - nevertheless Dir::Self is much simpler code.

Community::Prototypes does not recognize :prototype form for declaring prototypes

foo and baz get caught correctly. bat is ignored correctly because it's an empty prototype. bar should be caught but is not.

This looks like the same problem as Perl-Critic/Perl-Critic#978

#!/usr/bin/perl

use warnings;
use strict;
use 5.010;


sub foo($$) {}

sub bar :prototype($$) {}

sub bat() {}

sub baz($$) {}
$ perlcritic --s Community::Prototypes foo.pl
foo.pl: Using function prototypes.
    8:sub foo($$) {}

foo.pl: Using function prototypes.
    14:sub baz($$) {}

DollarAB false positive in dereference

use strict;
use warnings;

my @xs = (
    ['foo'],
    ['bar', 'baz'],
);

@xs = sort {
    my ($k1) = @{$a};
    my ($k2) = @{$b};
    $k1 cmp $k2
} @xs;
$ perlcritic bug.pl
Using $a or $b outside sort() at line 10, column 18.  $a and $b are special package variables for use in sort() and related functions. Declaring them as lexicals like "my $a" may break sort(). Use different variable names.  (Severity: 4)
Using $a or $b outside sort() at line 11, column 18.  $a and $b are special package variables for use in sort() and related functions. Declaring them as lexicals like "my $a" may break sort(). Use different variable names.  (Severity: 4)

:-(

Since rename, Freenode:: compatibility aliases are treated as distinct policies

The Freenode:: policies were recently renamed to Community::*, with backward compatibility aliases in the Freenode:: namespace. The backward compatibility aliases seem to be treated as distinct policies by perlcritic core, which means they're all being processed twice and configuration for Freenode::foo isn't applied to Community::foo or vice versa.

I noticed this when my project's CI broke because all of the Freenode:: policies that we turned off, got turned back on under their Community:: names. The most straightforward workaround seems to be to rewrite the main perlcritic configuration in terms of the Community:: names and then also list every single one of the Freenode:: names as disabled.

Another Freenode::DollarAB false negative

#!perl

use strict;
use warnings;

our $VERSION = "0.00";

my @b = 1..2;
my $x = $b[1]||" ";
$ perlcritic -1 test.pl
test.pl#9.9:    [4 - Freenode::DollarAB]        Using $a or $b outside sort()   :my $x = $b[1]||" ";

Old-style Freenode::* modules make redundant error checking

Consider this program foo.pl:

#!/var/perl/bin/perl

use 5.010;
use strict;
use warnings;

print $a;

If I run perlcritic on it, I get two errors:

$ perlcritic -2 -verbose='%f:%l:%c %m (%p)\n'  foo.pl
foo.pl:7:7 Using $a or $b outside sort() (Community::DollarAB)
foo.pl:7:7 Using $a or $b outside sort() (Community::DollarAB)

If I then create a Dev/perlcriticrc file like so:

[-Community::DollarAB]

and rerun I get only one error:

$ perlcritic -2 -verbose='%f:%l:%c %m (%p)\n' -p Dev/perlcriticrc foo.pl
foo.pl:7:7 Using $a or $b outside sort() (Community::DollarAB)

If I add

[-Freenode::DollarAB]

to my perlcriticrc, then it runs clean.

It looks like the Freenode::DollarAB aliasing to Community::DollarAB means I now have two policies checking on my code, and that I need to silence both of them. :-(

if (%bar) {} Is Probably Not A Good Suggestion

The suggestion to use if (%bar){} here should probably be replaced with if (keys %bar){}, as using a hash directly for this purpose is several orders of magnitude slower in some instances. Perl seems to be optimized to deal with the specific case of if (%hash){}, but the performance drops dramatically for, say, using unless, which isn't present with the keys %hash variant:

zoffix@:~$ perl -Mojo -wlE 'my %h = 1..1000_000; n { for(1..100){ unless(%h ){} } } 100'
4.80698 wallclock secs ( 4.79 usr +  0.01 sys =  4.80 CPU) @ 20.83/s (n=100)
zoffix@:~$ perl -Mojo -wlE 'my %h = 1..1000_000; n { for(1..100){ unless(keys %h){} } } 100'
0.000820875 wallclock secs ( 0.00 usr +  0.00 sys =  0.00 CPU)

Freenode::DeprecatedFeatures thinks << in formats are heredocs.

$ cat format.pl
#!/usr/bin/perl

use strict;
use warnings;

my $x = 14;
format STDOUT =
@<<<<<<<<<
$x
.

write STDOUT;
$ perl format.pl
14
$ perlcritic -s Freenode::DeprecatedFeatures format.pl
format.pl: Bare here-doc is deprecated.
    8:@<<<<<<<<<

format.pl: Bare here-doc is deprecated.
    8:@<<<<<<<<<

format.pl: Bare here-doc is deprecated.
    8:@<<<<<<<<<

format.pl: Bare here-doc is deprecated.
    8:@<<<<<<<<<

StrictWarnings cant deal with use 5.xx.y

#!/usr/bin/perl
use 5.14.2;
use warnings;
our $VERSION = "0.00";
say "hello";

Here 'use 5.14.2' implies 'use strict' (plus a bit more), and that would be the exception to the "version string used" warning.

$ perlcritic -1 xx.pl
Argument "^E^N^B" isn't numeric in numeric gt (>) at /pro/lib/perl5/site_perl/5.22.0/Perl/Critic/Policy/Freenode/StrictWarnings.pm line 57.
xx.pl#1.1:      [4 - Freenode::StrictWarnings]  Missing strict or warnings      :#!/usr/bin/perl
xx.pl#2.1:      [3 - ValuesAndExpressions::ProhibitVersionStrings]      Version string used     :use 5.14.2;

Perl::Critic::Policy::Freenode::DeprecatedFeatures doesn't understand postfix deref

The following snippet results in a perlcritic issue

use strict;
use warnings;

my $foo = {workers => {a => b => c =>4}};

if (keys $foo->workers->%* < 4) {
  print "Warnings";
}

autoderef is deprecated at line 6, column 5. Use of each/keys/pop/push/shift/splice/unshift/values on a reference is an experimental feature that is removed in perl v5.24.0. Dereference the array or hash to use these functions on it. (Severity: 4)

Warn that future Perl core changes might affect your script

Not sure if this is in scope for Perl::Critic::Freenode namespace, but for a while I was thinking - how nice it would be to have a module that reports deprecated/removed things in future Perl's than the one you are using.

It's a pain to implement and this can be already achieved by running your library against newer Perl versions ( perhaps with the help of Perlbrew or etc. ). Though, this would be great CI/code review tool.

Specifying freenode as the theme in .perlcriticrc doesn't work

When I put theme = freenode in .perlcriticrc I get an error message from perlcritic stating No policies selected. and exiting with error-code 255.

Shell session showing the issue:

[0]suppy@celestia:~/work/sbotools$ cat .perlcriticrc
theme = freenode
[0]suppy@celestia:~/work/sbotools$ perlcritic SBO-Lib/lib/SBO/Lib.pm
No policies selected.
[255]suppy@celestia:~/work/sbotools$ perlcritic --theme freenode SBO-Lib/lib/SBO/Lib.pm
SBO-Lib/lib/SBO/Lib.pm source OK
[0]suppy@celestia:~/work/sbotools$ env | grep -i perl
PERL5LIB=/home/suppy/perl5/lib/perl5
PERL_MB_OPT=--install_base "/home/suppy/perl5"
PATH=/home/suppy/perl5/bin:/home/suppy/.commands/:/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/lib64/kde4/libexec:/usr/lib64/qt/bin:/usr/share/texmf/bin
PERL_LOCAL_LIB_ROOT=/home/suppy/perl5
PERL_MM_OPT=INSTALL_BASE=/home/suppy/perl5
[0]suppy@celestia:~/work/sbotools$

Rename confuses Miscellanea::ProhibitUselessNoCritic

With the rename to Community (which I applaud), I saw Miscellanea::ProhibitUselessNoCritic violations where I hadn't before. When I removed the ## no critic (Freenode::Wantarray) I got the Community::Wantarray violation. Instead changing the ## no critic (Community::Wantarray) cleared the violations.

This is the CI fail:
https://github.com/perlwasm/Wasm/pull/112/checks?check_run_id=2694106399
and this is the workaround:
perlwasm/Wasm@62d30e1
(the commit also includes a change in the perlcritic rc file, but that wasn't required to clear the error, as per local testing)

Freenode::BarewordFileHandles dies on `open(CHECK, '/foo');`

Prompted by https://www.reddit.com/r/perl/comments/c4lhaq/and_most_damning_of_all_the_resulting_code_was/erx5hno/

The punchline is, of course, the 100 kB file keeper in http://www.ibiblio.org/pub/Linux/search/keeper-1.54.tar.gz. The code is so eyewateringly bad, it crashes Perl::Critic::Policy::InputOutput::ProhibitBarewordFileHandles. esr made a career out of bashing Perl, always blaming the language, never his own lack of skill.

$ cat minimal
#!/usr/bin/perl

open(CHECK, '/foo');
$ perlcritic minimal -s InputOutput::ProhibitBarewordFileHandles
Fatal error while critiquing "minimal": Not an ARRAY reference at /var/perl5.20.3/lib/site_perl/5.20.3/Perl/Critic/Policy/InputOutput/ProhibitBarewordFileHandles.pm line 35.

$ perlcritic minimal -s Freenode::BarewordFileHandles
Fatal error while critiquing "minimal": Not an ARRAY reference at /var/perl5.20.3/lib/site_perl/5.20.3/Perl/Critic/Policy/Freenode/BarewordFilehandles.pm line 47.

See also Perl-Critic/Perl-Critic#878

Allow for statement modifiers in EmptyReturn

EmptyReturn currently does not catch statements like return if $foo; This should be doable, it just needs to return the violation if the next element is a perl builtin which is a statement modifier.

#notallprototypes

Technically you just outlawed Try::Tiny.

I'd say prototypes with an & should be at least a lower level of violation since those are sometimes useful.

Constant interpolation triggers false DeprecatedFeatures positive

use constant CONSTANT => "foo";
my ($foo) = "foobar" =~ /(${\CONSTANT})/;

...yields

test.pl:2:25: /\C/ is deprecated. Use of the \C character class in regular expressions is deprecated in perl v5.20.0. To examine a string's UTF-8-encoded byte representation, encode it to UTF-8. [Community::DeprecatedFeatures]

If both Community and Freenode are enabled, Community settings seem to be ignored.

Perl 5.34, Perl::Critic::Community v1.0.2, Perl::Critic 1.140

If both Community and Freenode are enabled, Community settings seem to be ignored.

(As background, I don't use themes. I run against everything which I've installed, unless I explicitly exclude it. It's not currently documented in the top-level Community documentation that the same policies are also installed under the Freenode name. This caused me a bit of confusion during my debugging, as I was seeing Freenode policies and had never explicitly installed them.)

The following concocted code and perlcritic configuration illustrate the issue.

test code:

package Test;
use List::Util;
our $VERSION = 0.01;
1;

perlcritic.rc

verbose = 9
severity = brutal

exclude = TestingAndDebugging

[Community::StrictWarnings]
extra_importers = List::Util

I expect this to pass Community::StrictWarnings, but perlcritic returns:
[Community::StrictWarnings] Missing strict or warnings at line 1, near 'package Test;'. (Severity: 4)

I discovered that if I either

  1. explicitly exclude Freenode; or
  2. duplicate the settings under the Freenode::StrictWarnings namespace,

then the tests pass. It's not clear to me if the Freenode shims are just being reported as Community in the output or that they are actually hijacking Community's settings. Regardless, something is awry.

Thanks,
Diab

Misleading distinction between 'return' and 'return ()' in EmptyReturn

Hello,

This module advertises 'return ()' as correct and 'return' as incorrect, and actually reports the latter as a violation if I read the code correctly. This is misleading because these two forms are syntaxically completely equivalent. While I understand that this could be the object of an internal stylistic policy when writing the sub, it has no implication to the problem your Perl::Critic policy is trying to advert : being surprised by an unpredictable number of return values when calling the sub in list context.

I suggest you to collect all the return points of any sub and report a violation if they are possibly inconsistent (like having both a 'return' and a 'return $foo'). In particular, note that a conditional at the end of a sub yields a scalar value.

Vincent

Whitelist for DiscouragedModules/PreferredAlternatives

Sometimes you have no choice but to use a module on one of the discouraged lists. Right now, you have to turn the entire policy off to make perlcritic happy with that. It would be nice if it were possible to configure these policies with a list of specific modules to be allowed.

Example: I have a whole bunch of scripts that can only depend on core library modules, nothing from CPAN. They use FindBin; in the context it's used, it does the Right Thing. I'd like to be able to write something like

[Community::DiscouragedModules]
allow = FindBin

List::MoreUtils's message isn't very compelling

I came across this lint:

Used module List::MoreUtils at line 6, column 1. List::MoreUtils is a far more complex distribution than it needs to be. Use List::SomeUtils instead, or see List::Util or List::UtilsBy for alternatives.

and to me this reads as "this library is very fully featured and has everything you need :) don't use it!". I assume that since there is a lint for it there is a very good reason to avoid it. Maybe the message could include some information about the hazard?

strictures exporters

common::sense doesn't export a full set of warnings so doesn't count; I think sanity.pm does count but I dunno if it has enough revdeps to matter.

However the policy definitely needs to be configurable since I commonly end up with e.g.

package MyApp::Class;

use Import::Into;
use Moo ();
use MyApp::Utils ();

sub import {
    MyApp::Utils->import::into(1);
    Moo->import::into(1);
}

and a similar MyApp::Role - and obviously I'd then want the policy to accept those.

Policy to prohibit \d in regex without ascii flag

Requested by @plicease, a policy to catch use of \d to match digits where [0-9] was meant. Since it is valid but uncommon to match unicode digits this would be a severity 1 policy. Possibly also allowed with the /u flag indicating unicode is expected.

%sorters list in DollarAB does not have 'pairwise'

Thank you for a very useful policy of DollarAB, it is very helpful, let us catch a couple potential bugs in our codebase.

There's a caveat though- we're using pairwise in our code, and DollarAB complains about it. pairwise is exported by List::MoreUtils and List::AllUtils — granted, there's another policy that discourages using List::MoreUtils but getting rid of that dependency is not feasible for us at this time.

Can you please either add pairwise to the list, or, better yet, make the policy extensible so that the users could redefine the 'list of sorters' to suit their needs?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.