5 minimums for any perl script?

Sam Kington sam at illuminated.co.uk
Mon Jan 30 15:00:00 GMT 2012


On 30 Jan 2012, at 13:50, Guinevere Nell wrote:

> I would suggest that Perl::Critic, version control, and modularization
> combined with use of perldoc (instead of just comments with hoped for
> documentation to be made later/never) and make when a project is ready for
> production allow a high coding standard. If incorporated from the start
> they are easy to work with, and they encourage/force the programmers to
> keep readable, tidy, documented code.


One problem with perlcritic is that many of its rules, out of the box, are silly and annoying. You need to do a fair amount of tweaking to stop it bitching about stuff you don't care about, before you can get to the bits where it's actually useful. Here's $WORK's standard perlcriticrc:

severity = brutal
# Tell us which rule this violated, so we can tell it to fuck off.
verbose  = [%p] %m at %f line %l, near '%r'\n

### Git
# We use git, not svn or RCS
[-Miscellanea::RequireRcsKeywords]

# We'll enforce dependencies in other ways, rather than magically putting
# a $VERSION variable in modules.
[-Modules::RequireVersionVar]

### Modern Perl
# We'll run on at least perl 5.10
[Compatibility::PodMinimumVersion]
above_version = 5.010

### Chimera style
# No, you don't need to double-quote heredocs
[-ValuesAndExpressions::RequireQuotedHeredocTerminator]

# We *do* mean the difference between low- and high-precedence operators.
[-ValuesAndExpressions::ProhibitMixedBooleanOperators]

# Perltidy is a judgement call.
[-CodeLayout::RequireTidyCode]

# Damian Conway's insistence that the literal '' or "" in a proper
# monospaced font is difficult to read is frankly bizarre.
[-ValuesAndExpressions::ProhibitEmptyQuotes]
[-ValuesAndExpressions::ProhibitNoisyQuotes]

# There's muscle memory of always adding /xms to a regex, and then there's
# typing for the hell of it.
[-RegularExpressions::RequireDotMatchAnything]
[-RegularExpressions::RequireLineBoundaryMatching]

# Inline POD is good, dammit.
[-Documentation::RequirePodAtEnd]

# These are internal Perl modules. They don't need all these sections.
[-Documentation::RequirePodSections]

### We'll check this via code review, rather than automated tools.
# PPI can't tell the difference between methods (fine to use e.g. "delete")
# and subroutines (might trigger the indirect access mechanism by mistake),
# so this rule is useless.
[-Subroutines::ProhibitBuiltinHomonyms]

# This rule is also useless, as it doesn't know about named captures.
[-RegularExpressions::ProhibitUnusedCapture]

# Named captures also break this one.
[-Variables::ProhibitPunctuationVars]

# Tacit return values, or situations where it doesn't matter, are fine.
[-Subroutines::RequireFinalReturn]

# Similarly, if it compiles, who the hell cares what the last value was?
[-Modules::RequireEndWithOne]

# Double-sigil dereferences are almost certainly fine. The examples of bad
# stuff in PBP are straw men.
[-References::ProhibitDoubleSigils]

# Accessors that look at @_ before doing things are fine.
[-Subroutines::RequireArgUnpacking]

# Unless blocks are fine, possibly.
[-ControlStructures::ProhibitUnlessBlocks]

# Let a human decide whether range comparisons in an unless block are fine
[-ControlStructures::ProhibitNegativeExpressionsInUnlessAndUntilConditions]

# Likewise postfix if et al
[-ControlStructures::ProhibitPostfixControls]

# Some few modules need global variables. Let a human decide.
[-Variables::ProhibitPackageVars]

# Let use warnings warn about reusing a variable at the same lexical scope;
# this rule warns about reusing at a different scope, which is potentially
# fine.
[-Variables::ProhibitReusedNames]

# A lot of our code deals with pure ASCII. This stuff is probably fine.
[-RegularExpressions::ProhibitEnumeratedClasses]

# That trailing comma warning is annoying. Shut up.
[-CodeLayout::RequireTrailingCommaAtNewline]

# Don't require a final semicolon either.
[-CodeLayout::RequireFinalSemicolon]

# Far more numbers than 0, 1 and 2 are acceptable, but I can't be bothered
# configuring them. So, shut up. Code review will deal with this.
[-ValuesAndExpressions::ProhibitMagicNumbers]

# A blanket ban on parentheses around builtins is annoying, and over-zealous.
[-CodeLayout::ProhibitParensWithBuiltins]

# Putting braces around file handle objects is reasonable.
# Putting braces around bareword file handles like STDERR is frankly daft.
[-InputOutput::RequireBracedFileHandleWithPrint]

# reverse sort @array is indeed better than
# sort { $b cmp $a } @array
# I'm not so sure about hating on $b vs $a in e.g.
# sort { $b->{stuff} <=> $a->{stuff} }
[-BuiltinFunctions::ProhibitReverseSortBlock]

# This is overridden by the better rule RequireCheckedSyscalls
[-InputOutput::RequireCheckedClose]

# Nobody (hopefully) thinks that prototypes allow argument-checking.
# But they do allow syntactic sugar, which is why we use them in e.g. Moose.
[-Subroutines::ProhibitSubroutinePrototypes]

# This alerts unnecessarily for e.g. $foo = $1 if /.../ so skip it.
[-RegularExpressions::ProhibitCaptureWithoutTest]

### Modules that import strictures etc.
# We have use strict and use warnings, dammit
[TestingAndDebugging::RequireUseStrict]
equivalent_modules = common::sense our::way

[TestingAndDebugging::RequireUseWarnings]
equivalent_modules = common::sense our::way

[TestingAndDebugging::ProhibitNoWarnings]
allow = uninitialized

### Rule tweaking
# Loop labels are lower-case. Dancer packages can also be lower-case.
[NamingConventions::Capitalization]
labels = :all_lower
packages = :no_restriction

# Allow computed use statements.
[BuiltinFunctions::ProhibitStringyEval]
allow_includes = 1

# Let us mess about with %ENV. This wants to be system-wide.
[Variables::RequireLocalizedPunctuationVars]
allow = %ENV

# The default indirect syntax role only checks for "new", which is the
# one case which is fairly reasonable, if not ideal. So keep that check,
# but downgrade it.
[Objects::ProhibitIndirectSyntax]
severity = cruel

# Yes, require /x but perhaps not for really trivial regexen
[RegularExpressions::RequireExtendedFormatting]
minimum_regex_length_to_complain_about = 5

# Sometimes you need an if ... elsif ... elsif etc. chain; allow more,
# and make it less important.
[ControlStructures::ProhibitCascadingIfElse]
max_elsif = 3
severity = cruel

# Checking return values is a good thing. Checking the return value of
# close or print STDERR is downright silly.
[InputOutput::RequireCheckedSyscalls]
functions = :builtins
exclude_functions = print close


Sam
-- 
Website: http://www.illuminated.co.uk/




More information about the london.pm mailing list