4 use warnings FATAL => 'all';
7 *_PERL_LT_5_8_4 = ($] < 5.008004) ? sub(){1} : sub(){0};
10 our $VERSION = '1.005006';
11 $VERSION = eval $VERSION;
16 if (defined $_[1] && eval { $_[0]->UNIVERSAL::VERSION($_[1]); 1}) {
18 unless _PERL_LT_5_8_4;
19 $^H{strictures_enable} = int $_[1];
21 goto &UNIVERSAL::VERSION;
24 our %extra_load_states;
30 my %opts = ref $_[0] ? %{$_[0]} : @_;
31 if (!exists $opts{version}) {
33 = exists $^H{strictures_enable} ? delete $^H{strictures_enable}
36 $class->_enable(\%opts);
40 my ($class, $opts) = @_;
41 my $version = $opts->{version};
44 my $method = "_enable_$version";
45 if (!$class->can($method)) {
46 die "Major version specified as $version - not supported!";
48 $class->$method($opts);
53 warnings->import(FATAL => 'all');
55 _load_extras(qw(indirect multidimensional bareword::filehandles))
57 indirect->unimport(':fatal') if $extra_load_states{indirect};
58 multidimensional->unimport if $extra_load_states{multidimensional};
59 bareword::filehandles->unimport if $extra_load_states{'bareword::filehandles'};
64 my $extra_tests = do {
65 if (exists $ENV{PERL_STRICTURES_EXTRA}) {
66 if (_PERL_LT_5_8_4 and $ENV{PERL_STRICTURES_EXTRA}) {
67 die 'PERL_STRICTURES_EXTRA checks are not available on perls older than 5.8.4: '
68 . "please unset \$ENV{PERL_STRICTURES_EXTRA}\n";
70 $ENV{PERL_STRICTURES_EXTRA};
71 } elsif (! _PERL_LT_5_8_4) {
72 (caller(4))[1] =~ /^(?:t|xt|lib|blib)[\\\/]/
73 and defined $Smells_Like_VCS ? $Smells_Like_VCS
74 : ( $Smells_Like_VCS = !!(
75 -e '.git' || -e '.svn' || -e '.hg'
76 || (-e '../../dist.ini'
77 && (-e '../../.git' || -e '../../.svn' || -e '../../.hg' ))
85 foreach my $mod (@extras) {
87 if exists $extra_load_states{$mod};
89 $extra_load_states{$mod} = eval "require $mod; 1;" or do {
92 #work around 5.8 require bug
93 (my $file = $mod) =~ s|::|/|g;
94 delete $INC{"${file}.pm"};
99 my $failed = join ' ', @failed;
100 my $extras = join ' ', @extras;
102 strictures.pm extra testing active but couldn't load all modules. Missing were:
106 Extra testing is auto-enabled in checkouts only, so if you're the author
107 of a strictures-using module you need to run:
111 but these modules are not required by your users.
122 strictures - turn on strict and make all warnings fatal
131 use warnings FATAL => 'all';
133 except when called from a file which matches:
135 (caller)[1] =~ /^(?:t|xt|lib|blib)[\\\/]/
137 and when either C<.git>, C<.svn>, or C<.hg> is present in the current directory
138 (with the intention of only forcing extra tests on the author side) -- or when
139 C<.git>, C<.svn>, or C<.hg> is present two directories up along with
140 C<dist.ini> (which would indicate we are in a C<dzil test> operation, via
141 L<Dist::Zilla>) -- or when the C<PERL_STRICTURES_EXTRA> environment variable is
149 use warnings FATAL => 'all';
152 no bareword::filehandles;
154 Note that C<PERL_STRICTURES_EXTRA> may at some point add even more tests, with
155 only a minor version increase, but any changes to the effect of C<use
156 strictures> in normal mode will involve a major version bump.
158 If any of the extra testing modules are not present, L<strictures> will
159 complain loudly, once, via C<warn()>, and then shut up. But you really
160 should consider installing them, they're all great anti-footgun tools.
164 I've been writing the equivalent of this module at the top of my code for
165 about a year now. I figured it was time to make it shorter.
167 Things like the importer in C<use Moose> don't help me because they turn
168 warnings on but don't make them fatal -- which from my point of view is
169 useless because I want an exception to tell me my code isn't warnings-clean.
171 Any time I see a warning from my code, that indicates a mistake.
173 Any time my code encounters a mistake, I want a crash -- not spew to STDERR
174 and then unknown (and probably undesired) subsequent behaviour.
176 I also want to ensure that obvious coding mistakes, like indirect object
177 syntax (and not so obvious mistakes that cause things to accidentally compile
178 as such) get caught, but not at the cost of an XS dependency and not at the
179 cost of blowing things up on another machine.
181 Therefore, L<strictures> turns on additional checking, but only when it thinks
182 it's running in a test file in a VCS checkout -- although if this causes
183 undesired behaviour this can be overridden by setting the
184 C<PERL_STRICTURES_EXTRA> environment variable.
186 If additional useful author side checks come to mind, I'll add them to the
187 C<PERL_STRICTURES_EXTRA> code path only -- this will result in a minor version
188 increase (e.g. 1.000000 to 1.001000 (1.1.0) or similar). Any fixes only to the
189 mechanism of this code will result in a sub-version increase (e.g. 1.000000 to
192 If the behaviour of C<use strictures> in normal mode changes in any way, that
193 will constitute a major version increase -- and the code already checks
194 when its version is tested to ensure that
198 will continue to only introduce the current set of strictures even if 2.0 is
205 This method does the setup work described above in L</DESCRIPTION>
209 This method traps the C<< strictures->VERSION(1) >> call produced by a use line
210 with a version number on it and does the version check.
212 =head1 EXTRA TESTING RATIONALE
214 Every so often, somebody complains that they're deploying via C<git pull>
215 and that they don't want L<strictures> to enable itself in this case -- and that
216 setting C<PERL_STRICTURES_EXTRA> to 0 isn't acceptable (additional ways to
217 disable extra testing would be welcome but the discussion never seems to get
220 In order to allow us to skip a couple of stages and get straight to a
221 productive conversation, here's my current rationale for turning the
222 extra testing on via a heuristic:
224 The extra testing is all stuff that only ever blows up at compile time;
225 this is intentional. So the oft-raised concern that it's different code being
226 tested is only sort of the case -- none of the modules involved affect the
227 final optree to my knowledge, so the author gets some additional compile
228 time crashes which he/she then fixes, and the rest of the testing is
229 completely valid for all environments.
231 The point of the extra testing -- especially C<no indirect> -- is to catch
232 mistakes that newbie users won't even realise are mistakes without
237 where foo is an & prototyped sub that you forgot to import -- this is
238 pernicious to track down since all I<seems> fine until it gets called
239 and you get a crash. Worse still, you can fail to have imported it due
240 to a circular require, at which point you have a load order dependent
241 bug which I've seen before now I<only> show up in production due to tiny
242 differences between the production and the development environment. I wrote
243 L<http://shadow.cat/blog/matt-s-trout/indirect-but-still-fatal/> to explain
244 this particular problem before L<strictures> itself existed.
246 As such, in my experience so far L<strictures>' extra testing has
247 I<avoided> production versus development differences, not caused them.
249 Additionally, L<strictures>' policy is very much "try and provide as much
250 protection as possible for newbies -- who won't think about whether there's
251 an option to turn on or not" -- so having only the environment variable
252 is not sufficient to achieve that (I get to explain that you need to add
253 C<use strict> at least once a week on freenode #perl -- newbies sometimes
254 completely skip steps because they don't understand that that step
257 I make no claims that the heuristic is perfect -- it's already been evolved
258 significantly over time, especially for 1.004 where we changed things to
259 ensure it only fires on files in your checkout (rather than L<strictures>-using
260 modules you happened to have installed, which was just silly). However, I
261 hope the above clarifies why a heuristic approach is not only necessary but
262 desirable from a point of view of providing new users with as much safety as
263 possible, and will allow any future discussion on the subject to focus on "how
264 do we minimise annoyance to people deploying from checkouts intentionally".
280 L<bareword::filehandles>
284 =head1 COMMUNITY AND SUPPORT
288 irc.perl.org #toolchain
290 (or bug 'mst' in query on there or freenode)
292 =head2 Git repository
294 Gitweb is on http://git.shadowcat.co.uk/ and the clone URL is:
296 git clone git://git.shadowcat.co.uk/p5sagit/strictures.git
298 The web interface to the repository is at:
300 http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit/strictures.git
304 mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
308 Karen Etheridge (cpan:ETHER) <ether@cpan.org>
310 Mithaldu - Christian Walde (cpan:MITHALDU) <walde.christian@gmail.com>
312 haarg - Graham Knop (cpan:HAARG) <haarg@haarg.org>
316 Copyright (c) 2010 the strictures L</AUTHOR> and L</CONTRIBUTORS>
321 This library is free software and may be distributed under the same terms