1Perl::Critic::CORE_DEVEULsOePrERC(o3n)tributed Perl DocuPmeernlt:a:tCirointic::CORE_DEVELOPER(3)
2
3
4

NAME

6       Perl::Critic::CORE_DEVELOPER - Hints for working on the Perl::Critic
7       core.
8

DESCRIPTION

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

BECOMING A CORE DEVELOPER

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

ADDING A GLOBAL CONFIGURATION ITEM

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
135       item as an attribute value, defaulting it if necessary. Using our
136       naming convention, a single-valued item would be stored like this:
137
138           $self->{_new_item} = dor(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), the "dor()" call must check for all of them. If the item
143       took a list of values, they would be parsed apart and stored as an
144       array reference.
145
146       You must also add and document an accessor for your new item. This
147       would look something like this:
148
149           sub new_item {
150               my ($self) = @_;
151               return $self->{_new_item};
152           }
153
154       In the case of multi-valued items, the accessor must return the array
155       reference, so the above specimen code works in that case also.
156
157       Note that no validation is done here -- this class is simply a bridge
158       between the physical .perlcriticrc file and Perl::Critic::Config, which
159       is where the action is.
160
161       If your new item is a command option without a corresponding global
162       configuration item, you do not need to modify this file.
163
164       lib/Perl/Critic/Config.pm
165
166       You must write a "_validate_and_store_new_item()" method to validate
167       and store the value of the new item. The signature of this method
168       depends on the details of your new item, but it must include at least
169       the value of the item, even if there is no corresponding global
170       configuration item. If it is possible to get validation failures, it
171       will also need an errors object to add the validation exception to.
172       Because the details vary, the best way to proceed is probably to find a
173       method similar to the one you want to write, and implement from there.
174       The "_validate_and_store_top()" method is a reasonable starting point
175       for an item having a single value. The validated value needs to be
176       stored in "$self->{_new_item}".
177
178       You must call "_validate_and_store_new_item()" in the "_init()" method.
179
180       You must write and document an accessor method for the value of the new
181       item. The typical accessor method for a single-valued item is
182
183           sub new_item {
184               my ($self) = @_;
185               return $self->{_new_item};
186           }
187
188       but the accessor for a multi-valued item must return a list:
189
190           sub new_item {
191               my ($self) = @_;
192               return @{ $self->{_new_item} };
193           }
194
195       Last, you must document the item itself.
196
197       lib/Perl/Critic/ProfilePrototype.pm
198
199       If your new item has a corresponding global configuration item, you
200       must update the "to_string()" method to include the item in the string.
201       Your implementation of the item must be such that the generated string
202       is the same as the input string for the item, except for whitespace.
203
204       If your new item has no corresponding global configuration item, you do
205       not need to change this file.
206
207       bin/perlcriticrc
208
209       If your new item has a corresponding command option, you must document
210       it here. If it does not, you do not need to change this file.
211
212       examples/perlcriticrc
213
214       If your new item has a corresponding global configuration item, you
215       must add it here. If it does not, you do not need to change this file.
216
217   Testing
218       The following test files must be considered for modification:
219
220           t/00_modules.t
221           t/01_config.t
222           t/01_config_bad_perlcritic.t
223           t/04_options_processor.t
224           t/07_command.t
225           t/10_user_profile.t
226           t/16_roundtrip_defaults.t
227
228       Depending on your new item, you may not need to change all of these,
229       but you should at least review them. Depending on what your new item
230       actually does, other test files may need to be modified as well.
231

DEPRECATING AND REMOVING A PUBLIC SUBROUTINE OR METHOD

233       This is something to be done cautiously. The code in question may only
234       exist to serve Perl::Critic, but if it is documented as public it may
235       well be in use "in the wild", either in add-ons to Perl::Critic or by
236       users of Perl::Critic.
237
238       Before deprecating public code, the potential deprecator must discuss
239       the issues on the Perl::Critic developers' mailing list. There are
240       instructions on how to subscribe to this list in "EXTENDING THE CRITIC"
241       in Perl::Critic.
242
243       Once agreement is reached, the technical details of the deprecation are
244       fairly simple.
245
246       You must insert something like the following in the code to be
247       deprecated:
248
249           warnings::warnif(
250               'deprecated',
251               'Perl::Critic::Utils::foo() deprecated, use blah::foo() instead.',
252           );
253
254       You should have the deprecated subroutine delegate its functionality to
255       the new subroutine, if that is practical (it may not be).
256
257       You must update the documentation to say that the old code is
258       deprecated, and what the replacement is.
259
260       After the old code has been deprecated for a couple production
261       releases, it can be removed.
262

AUTHOR

264       Thomas R. Wyant, III wyant at cpan dot org
265
267       Copyright (c) 2009-2011 Thomas R. Wyant, III
268
269       This program is free software; you can redistribute it and/or modify it
270       under the same terms as Perl itself.  The full text of this license can
271       be found in the LICENSE file included with this module.
272
273
274
275perl v5.30.1                      2020-01-30   Perl::Critic::CORE_DEVELOPER(3)
Impressum