→ Use code to optimize for you!
lint for Perlstrict.pm which is a runtime live
code analyzerTest::Perl::Critic
by Jeffrey Ryan Thalhammer and crew
Loaded via Module::PluggableBuilt on top of PPI, the pure-perl Perl parser.
% ppidump 'print "Hello, World";'
PPI::Document
PPI::Statement
PPI::Token::Word 'print'
PPI::Token::Whitespace ' '
PPI::Token::Quote::Double '"Hello, World"'
PPI::Token::Structure ';'
% cpan install Perl::Critic
% perlcritic PerfectCode.pm
# OK
% perlcritic LegacyCode.pm
Code before strictures are enabled at line 3, column 1. See page 429 of PBP. (Severity: 5)
Expression form of 'eval' at line 4, column 4. See page 161 of PBP. (Severity: 5)
%
use Test::Perl::Critic; all_critic_ok();
(for example in t/perlcritic.t)
Upload code via http://perlcritic.com/
Lenient (the default)
% perlcritic -5 Foo.pm
Typical
% perlcritic -3 Foo.pm
Pedantic
% perlcritic -1 Foo.pm
Examples:
RequireBarewordIncludes
require "lib/Foo.pm"; vs. require Foo;
ProhibitExplicitISA
@ISA = qw(Foo); vs. use base 'Foo';
ProhibitParensWithBuiltins
print("foo\n"); vs. print "foo\n";
Create a ~/.perlcriticrc file
[-CodeLayout::RequireTidyCode]
[-ControlStructures::ProhibitCStyleForLoops]
[-Documentation::RequirePodAtEnd]
[-Documentation::RequirePodSections]
[-Miscellanea::RequireRcsKeywords]
[-NamingConventions::ProhibitMixedCaseSubs]
[ControlStructures::ProhibitCascadingIfElse]
max_elsif = 3
Perl::Critic has flags to ignore special cases
## no critic at the end of a line## no critic
... code ...
## use critic$email = 'foo@bar.com'; ## no critic(RequireInterpolation)
sub _calc_xml_paths { ## no critic(ExcessComplexity)
... lots of code ...
}
Pick a useful goal: detect calls to undeclared functions.
sub main {
output_strnig('Hello, World!');
}
sub output_string {
my ($msg) = @_;
print $msg, "\n";
}
Create a file: t/Subroutines/ProhibitUndeclaredSub.run
## name sub exists
## failures 0
foo();
sub foo { }
## name sub missing
## failures 1
bar();
Run: ppidump 'bar();'
PPI::Document
PPI::Statement
PPI::Token::Word 'bar'
PPI::Structure::List ( ... )
PPI::Token::Structure ';'
Run: ppidump 'sub foo { print; }'
PPI::Document
PPI::Statement::Sub
PPI::Token::Word 'sub'
PPI::Token::Word 'foo'
PPI::Structure::Block { ... }
PPI::Statement
PPI::Token::Word 'print'
PPI::Token::Structure ';'
package Perl::Critic::Policy::
Subroutines::ProhibitUndeclaredSub;
use warnings;
use strict;
use Perl::Critic::Utils;
use base 'Perl::Critic::Policy';
sub applies_to {
return 'PPI::Token::Word';
}