1Perl::Critic::DEVELOPERU(s3e)r Contributed Perl DocumentaPteiroln::Critic::DEVELOPER(3)
2
3
4
6 Perl::Critic::DEVELOPER - How to make new Perl::Critic::Policy modules
7
9 This document describes how to create a new Policy module for
10 Perl::Critic. It is intended for developers who wish to extend
11 Perl::Critic to enforce their own custom coding standards. Although
12 the Perl::Critic distribution already includes a number of Policies
13 based on Damian Conway's book "Perl Best Practices", Perl::Critic is
14 not limited to his guidelines and can be used to enforce any practice,
15 preference, or style that you want to follow. In fact, you can even
16 write Policies to enforce contradictory guidelines. All you need to do
17 is write a corresponding Perl::Critic::Policy subclass, which may
18 require as little as 10 lines of code..
19
21 The heart of Perl::Critic is PPI, which is a parser and lexer for Perl.
22 PPI transforms a file of Perl source code into a Document Object Model
23 (DOM). Each token in the document is represented by one of the various
24 PPI classes (for example: PPI::Token::Operator, PPI::Token::Word). The
25 tokens are then organized into a hierarchy of structural classes (for
26 example: PPI::Statement::Expression, PPI::Structure::Subroutine). The
27 root node of the hierarchy is the PPI::Document.
28
29 The Perl::Critic engine traverses each node in the PPI::Document tree
30 and invokes each of the Perl::Critic::Policy subclasses at the appro‐
31 priate node. The Policy can inspect the node, look at the surrounding
32 nodes, and do whatever else it wants. If the Policy decides that that
33 a coding standard has been violated, it returns one or more
34 Perl::Critic::Violation objects. If there are no violations, then the
35 Policy returns nothing.
36
37 So now that we understand the basic organization of PPI and
38 Perl::Critic, lets examine one the existing Policy modules so we can
39 see how this all works. We will pick the RequireBlockGrep.pm policy
40 because it is relatively simple but demonstrates most of the important
41 issues. The goal of this Policy is to enforce that every call to
42 "grep" uses a block for the first argument and not an expression. The
43 reasons for this Policy are discussed in detail in "Perl Best Prac‐
44 tices."
45
47 First, the Policy module needs to have a name. Perl::Critic uses Mod‐
48 ule::Pluggable to automatically discover all modules that are in the
49 "Perl::Critic::Policy" namespace. Also, we've adopted the convention
50 of grouping Policies into directories according to the table of con‐
51 tents in Conway's book "Perl Best Practices." Since the goal of this
52 policy is to enforce the use of block arguments to "grep" and it comes
53 from the "Builtin Functions" chapter of PBP, we call it
54 "Perl::Critic::Policy::BuiltinFunctions::RequireBlockGrep".
55
56 package Perl::Critic::Policy::BuiltinFunctions::RequireBlockGrep;
57
58 Next, we set some pragmas and load the modules that we'll need. All
59 Policy modules inherit from the Perl::Critic::Policy class, which pro‐
60 vides no-op implementations of the basic methods. Our job is to over‐
61 ride these methods to make them do something useful.
62
63 Technically, "use strict" and "use warnings" are optional, but they are
64 necessary to make Perl::Critic self-compliant. And we don't want
65 Perl::Critic to be a hypocrite, now do we?
66
67 use strict;
68 use warnings;
69 use Perl::Critic::Utils;
70 use Perl::Critic::Violation;
71 use base 'Perl::Critic::Policy';
72
73 our $VERSION = '0.22';
74
75 Next, we'll declare a description and explanation for this Policy. The
76 description is always just a string that basically says "this is what's
77 wrong." The explanation can be either a string with further details,
78 or a reference to an array of integers that correspond to page numbers
79 in the "Perl Best Practices" book.
80
81 my $desc = q{Expression form of "grep"};
82 my $expl = [169];
83
84 Most policies don't need to override the new() method provided by
85 Perl::Critic::Policy. However, if your policy is configurable via
86 .perlcriticrc you will need to override the constructor to examine the
87 %args values. See Perl::Critic::Policy::ControlStructures::Prohibit‐
88 CascadingIfElse for a simple example and Perl::Critic::Policy::Documen‐
89 tation::RequirePodSections for a more complex example.
90
91 Next, we define the "default_severity()" method, which should return a
92 scalar value indicating the severity of violating this Policy. Sever‐
93 ity values range from 1 to 5, where 5 is the "most severe." In gen‐
94 eral, level 5 is reserved for things that are frequently misused and/or
95 cause bugs. Level 1 is for things that are highly subjective or purely
96 cosmetic. The Perl::Critic::Utils package exports several severity
97 constants that you can use here.
98
99 sub default_severity { return $SEVERITY_HIGH }
100
101 Likewise, the "default_themes()" method returns a list of theme names.
102 Themes are intended to be named groups of Policies. All Policies that
103 ship with Perl::Critic have a "core" theme. And since this Policy
104 comes directly from Damian's "Perl Best Practices" book, this Policy
105 should be a member of the "pbp" theme.
106
107 sub default_themes { return qw( core pbp ) }
108
109 As a Policy author, you can assign any themes you want to the Policy.
110 If you're publishing a suite of custom Policies, we suggest that you
111 create a unique theme that covers all the Policies in the distribution.
112 That way, users can easily enable or disable all of your policies at
113 once.
114
115 Next, we indicate what elements of the code this policy will analyze,
116 like statements or variables or conditionals or POD. These elements
117 are specified as PPI classes such as PPI::Statement, PPI::Token::Sym‐
118 bol, PPI::Structure::Conditional or PPI::Token::Pod respectively. The
119 applies_to() method returns a list of PPI package names. (You can get
120 that list of available package names via "perldoc PPI".) As
121 Perl::Critic traverses the document, it will call the "violates()"
122 method from this module whenever it encounters one of the PPI types
123 that are given here. In this case, we just want to test calls to
124 "grep". Since the token "grep" is a PPI::Token::Word, we return that
125 package name from the "applies_to()" method.
126
127 sub applies_to { return 'PPI::Token::Word' }
128
129 If your Policy needs to analyze several different types of elements,
130 the "applies_to" method may return the name of several PPI packages.
131 If your Policy needs to examine the file as a whole, then the
132 "applies_to" method should return PPI::Document. Since there is only
133 one PPI::Document element, such a Policy would only be invoked once per
134 file.
135
136 Now comes the interesting part. The "violates()" method does all the
137 work. It is always called with 2 arguments: a reference to the current
138 PPI element that Perl::Critic is traversing, and a reference to the
139 entire PPI document. [And since this is an object method, there will be
140 an additional argument that is a reference to this object ($self), but
141 you already knew that!]
142
143 sub violates {
144 my ( $self, $elem, $doc ) = @_;
145
146 The violates() method then often performs some tests to make sure we
147 have the right "type" of element. In our example, we know that the
148 element will be a PPI::Token::Word because that's what we declared back
149 in the "applies_to()" method. However, we didn't specify exactly which
150 "word" we were looking for. Evaluating a PPI element in a string con‐
151 text returns the literal form of the code. So we make sure that this
152 PPI::Token::Word is, in fact, "grep". If it's not, then we don't' need
153 to bother examining it.
154
155 return if $elem ne 'grep';
156
157 The "PPI::Token::Word" class is also used for barewords and methods
158 called on object references. It is possible for someone to declare a
159 bareword hash key as "<%hash = ( grep =" 'foo' )>>. We don't want to
160 test those types of elements because they don't represent function
161 calls to "grep". So we use some handy utility functions from
162 Perl::Critic::Utils to make sure that this "grep" is actually in the
163 right context.
164
165 return if is_method_call($elem);
166 return if is_hash_key($elem);
167 return if is_subroutine_name($elem);
168
169 Now that we know this element is a call to the "grep" function, we can
170 look at the nearby elements to see what kind of arguments are being
171 passed to it. Every PPI element is linked to its siblings, parent, and
172 children (if it has any). Since those siblings could just be white‐
173 space, we use the "snext_sibling()" to get the next code-sibling (the
174 's' in "snext_sibling" stands for 'significant').
175
176 my $sib = $elem->snext_sibling() ⎪⎪ return;
177
178 In Perl, the parenthesis around argument lists are usually optional,
179 and PPI packs the elements into a PPI::Structure::List object when
180 parens are used. So if the sibling is a PPI::Structure::List, we pull
181 out the first (significant) child of that list. This child will be the
182 first argument to "grep". If parens were not used, then the sibling
183 itself is the first argument.
184
185 my $arg = $sib->isa('PPI::Structure::List') ? $sib->schild(0) : $sib;
186
187 Finally, we now have a reference to the first argument to "grep". If
188 that argument is a block (i.e. something in curly braces), then it will
189 be a PPI::Structure::Block, in which case our Policy is satisfied and
190 we just return nothing.
191
192 return if !$arg ⎪⎪ $arg->isa('PPI::Structure::Block');
193
194 But if it is not a PPI::Structure::Block, then we know that this call
195 to "grep" must be using the expression form, and that violates our Pol‐
196 icy. So we create and return a new Perl::Critic::Violation object,
197 passing in the description, explanation, and severity of the violation,
198 as well as a reference to the PPI element that caused the violation.
199 And that's all there is to it!
200
201 my $sev = $self->get_severity();
202 return Perl::Critic::Violation->new( $desc, $expl, $elem, $sev );
203 }
204
205 1;
206
207 One last thing -- When you import Perl::Critic::Violation, it extracts
208 the DESCRIPTION section from the POD in your Policy module. That text
209 can displayed in the diagnostic output when the Violations objects are
210 stringified. So please include a DESCRIPTION section in the POD for
211 your Policy. It should succinctly describe the behavior and motivation
212 for your Policy and include a few examples of both good and bad code.
213 Here's an example:
214
215 =pod
216
217 =head1 NAME
218
219 Perl::Critic::Policy::BuiltinFunctions::RequireBlockGrep
220
221 =head1 DESCRIPTION
222
223 The expression form of C<grep> and C<map> is awkward and hard to read.
224 Use the block forms instead.
225
226 @matches = grep /pattern/, @list; #not ok
227 @matches = grep { /pattern/ } @list; #ok
228
229 @mapped = map transform($_), @list; #not ok
230 @mapped = map { transform($_) } @list; #ok
231
232 =cut
233
235 Jeffrey Ryan Thalhammer <thaljef@cpan.org>
236
238 Copyright (c) 2005-2007 Jeffrey Ryan Thalhammer. All rights reserved.
239
240 This program is free software; you can redistribute it and/or modify it
241 under the same terms as Perl itself. The full text of this license can
242 be found in the LICENSE file included with this module.
243
244
245
246perl v5.8.8 2007-03-20 Perl::Critic::DEVELOPER(3)