1Perl::Critic::CORE_DEVEULsOePrERC(o3n)tributed Perl DocuPmeernlt:a:tCirointic::CORE_DEVELOPER(3)
2
3
4
6 Perl::Critic::CORE_DEVELOPER - Hints for working on the Perl::Critic
7 core.
8
10 This document is a grab-bag of notes for those who are working on the
11 underpinnings of Perl::Critic. They are intended to be informative, but
12 unfortunately can not really be considered authoritative. It is in the
13 nature of the task being described that the user of this document will
14 end up working out the details for him- or herself based on the actual
15 work being performed. Caveat lector.
16
18 Here are my thoughts on how to get started. Note that the steps are not
19 numbered because I'm not sure there is a clear order to them. The items
20 with two stars in front of them are from the mailing list; the ones
21 with one star are my opinion. Although sometimes I have felt it helpful
22 to comment on the two-star items, just to make things thoroughly
23 unclear.
24
25 * If you're unsure of yourself, install Perl::Critic, then download the
26 source and rummage around in it.
27
28 ** Subscribe to the developers' mailing list. There are instructions in
29 "EXTENDING THE CRITIC" in Perl::Critic. The commits mailing list is
30 another good one.
31
32 ** If you are working on a GitHub issue, you should update the ticket
33 to say that you are, to keep other people from duplicating your effort.
34
35 * I personally would update GitHub at the point I was reasonably
36 confident I could hack it, just to prevent myself from having to update
37 GitHub again in a week or so saying "oops, bit off more than I could
38 chew." But that's me talking.
39
40 * Development requires using Module::Build rather than
41 ExtUtils::MakeMaker. In other words,
42
43 $ perl Build.PL
44 $ ./Build
45 $ ./Build test
46
47 * You need to run the suite of author tests by running
48
49 $ ./Build authortest
50
51 (but not 'make authortest', which is one of the reasons you should
52 start with Build.PL rather than Makefile.PL) These should run cleanly
53 before you declare your work done. My advice, though, is not to worry
54 about them until your code is functionally correct.
55
56 Modules required for authortest
57 The authortest requires a bunch of modules above and beyond those
58 required to run "Perl::Critic". The list probably depends on which
59 "Perl::Critic" you are testing, so the following should not be
60 considered definitive. You need the following in addition to all
61 optional modules for Perl::Critic itself.
62
63 Devel::EnforceEncapsulation
64 Perl::Critic::More
65 Test::Kwalitee
66 Test::Memory::Cycle
67 Test::Perl::Critic
68 Test::Pod
69 Test::Pod::Coverage
70 Test::Without::Module
71
72 You can find out what the optional modules are by looking at
73 recommended_module_versions() in inc/Perl/Critic/BuildUtilities.pm.
74
75 In the absence of "Test::Memory::Cycle", the relevant tests are simply
76 skipped. In the absence of the other modules, the tests die horribly.
77 Of course, either way they do not get run, so the difference is mainly
78 one of aesthetics.
79
80 Under Perl 5.12 and above, Devel::Cycle 1.11 needs to be patched to
81 handle a "Regexp" as a first-class Perl object. See
82 <https://rt.cpan.org/Public/Bug/Display.html?id=56681> for the details.
83
85 Perlcritic handles global configuration items and command line options
86 in very similar ways. These notes will cover adding both a global
87 configuration item and a corresponding, same-named command option.
88 These notes can not, of course, cover implementing the functionality of
89 the new item, just the mechanics of getting the item into Perl::Critic.
90
91 Naming Conventions
92 All names are lower-case, except for the names of constants (if any),
93 which are upper-case. When a name contains multiple words, dashes will
94 be used to separate the words in the configuration item name and the
95 command line option, and underscores will be used in the accessor and
96 attribute value names, and constant names if any.
97
98 For example, if "new item" is being added, the configuration item is
99 "new-item", the command option is "--new-item", the accessors are
100 new_item(), and the value of the attribute will be stored in
101 "$self->{_new_item}". If there are constants involved, their names will
102 start with "NEW_ITEM_". These names will be used in the following
103 discussion.
104
105 Implementation
106 There are several files that must be modified to get your new
107 configuration item and/or command line option.
108
109 lib/Perl/Critic/Utils/Constants.pm
110
111 If there are manifest constants connected with your implementation they
112 go here. You may well at least have a
113
114 $NEW_ITEM_DEFAULT
115
116 to define. All the constants for your new item must be exported, and
117 should be exported not only individually but all together with export
118 tag
119
120 new_item
121
122 lib/Perl/Critic/Command.pm
123
124 If your new item is a command option, its Getopt::Long specification
125 must be defined in _get_option_specification(). If your new
126 configuration item does not have a corresponding command option, you do
127 not need to make any changes to this file.
128
129 lib/Perl/Critic/OptionsProcessor.pm
130
131 If your new item is a global configuration item, you need to add the
132 code to handle it here. Specifically:
133
134 You must add code to the _init() method to store the value of your item
135 as an attribute value, defaulting it if necessary. Using our naming
136 convention, a single-valued item would be stored like this:
137
138 $self->{_new_item} = delete $args{'new-item'} //
139 $NEW_ITEM_DEFAULT;
140
141 If the item has synonyms (e.g. both 'color' and 'colour' meaning the
142 same thing), you must check for all of them. If the item took a list of
143 values, they would be parsed apart and stored as an array reference.
144
145 You must also add and document an accessor for your new item. This
146 would look something like this:
147
148 sub new_item {
149 my ($self) = @_;
150 return $self->{_new_item};
151 }
152
153 In the case of multi-valued items, the accessor must return the array
154 reference, so the above specimen code works in that case also.
155
156 Note that no validation is done here -- this class is simply a bridge
157 between the physical .perlcriticrc file and Perl::Critic::Config, which
158 is where the action is.
159
160 If your new item is a command option without a corresponding global
161 configuration item, you do not need to modify this file.
162
163 lib/Perl/Critic/Config.pm
164
165 You must write a _validate_and_store_new_item() method to validate and
166 store the value of the new item. The signature of this method depends
167 on the details of your new item, but it must include at least the value
168 of the item, even if there is no corresponding global configuration
169 item. If it is possible to get validation failures, it will also need
170 an errors object to add the validation exception to. Because the
171 details vary, the best way to proceed is probably to find a method
172 similar to the one you want to write, and implement from there. The
173 _validate_and_store_top() method is a reasonable starting point for an
174 item having a single value. The validated value needs to be stored in
175 "$self->{_new_item}".
176
177 You must call _validate_and_store_new_item() in the _init() method.
178
179 You must write and document an accessor method for the value of the new
180 item. The typical accessor method for a single-valued item is
181
182 sub new_item {
183 my ($self) = @_;
184 return $self->{_new_item};
185 }
186
187 but the accessor for a multi-valued item must return a list:
188
189 sub new_item {
190 my ($self) = @_;
191 return @{ $self->{_new_item} };
192 }
193
194 Last, you must document the item itself.
195
196 lib/Perl/Critic/ProfilePrototype.pm
197
198 If your new item has a corresponding global configuration item, you
199 must update the to_string() method to include the item in the string.
200 Your implementation of the item must be such that the generated string
201 is the same as the input string for the item, except for whitespace.
202
203 If your new item has no corresponding global configuration item, you do
204 not need to change this file.
205
206 bin/perlcriticrc
207
208 If your new item has a corresponding command option, you must document
209 it here. If it does not, you do not need to change this file.
210
211 examples/perlcriticrc
212
213 If your new item has a corresponding global configuration item, you
214 must add it here. If it does not, you do not need to change this file.
215
216 Testing
217 The following test files must be considered for modification:
218
219 t/00_modules.t
220 t/01_config.t
221 t/01_config_bad_perlcritic.t
222 t/04_options_processor.t
223 t/07_command.t
224 t/10_user_profile.t
225 t/16_roundtrip_defaults.t
226
227 Depending on your new item, you may not need to change all of these,
228 but you should at least review them. Depending on what your new item
229 actually does, other test files may need to be modified as well.
230
232 This is something to be done cautiously. The code in question may only
233 exist to serve Perl::Critic, but if it is documented as public it may
234 well be in use "in the wild", either in add-ons to Perl::Critic or by
235 users of Perl::Critic.
236
237 Before deprecating public code, the potential deprecator must discuss
238 the issues on the Perl::Critic developers' mailing list. There are
239 instructions on how to subscribe to this list in "EXTENDING THE CRITIC"
240 in Perl::Critic.
241
242 Once agreement is reached, the technical details of the deprecation are
243 fairly simple.
244
245 You must insert something like the following in the code to be
246 deprecated:
247
248 warnings::warnif(
249 'deprecated',
250 'Perl::Critic::Utils::foo() deprecated, use blah::foo() instead.',
251 );
252
253 You should have the deprecated subroutine delegate its functionality to
254 the new subroutine, if that is practical (it may not be).
255
256 You must update the documentation to say that the old code is
257 deprecated, and what the replacement is.
258
259 After the old code has been deprecated for a couple production
260 releases, it can be removed.
261
263 Thomas R. Wyant, III wyant at cpan dot org
264
266 Copyright (c) 2009-2011 Thomas R. Wyant, III
267
268 This program is free software; you can redistribute it and/or modify it
269 under the same terms as Perl itself. The full text of this license can
270 be found in the LICENSE file included with this module.
271
272
273
274perl v5.36.0 2023-03-05 Perl::Critic::CORE_DEVELOPER(3)