avoid goto UNIVERSAL::VERSION on 5.6
[p5sagit/strictures.git] / lib / strictures.pm
CommitLineData
394c3a46 1package strictures;
2
3use strict;
4use warnings FATAL => 'all';
5
500f28df 6BEGIN {
7 *_PERL_LT_5_8_4 = ($] < 5.008004) ? sub(){1} : sub(){0};
24590d98 8 *_CAN_GOTO_VERSION = ($] >= 5.008000) ? sub(){1} : sub(){0};
500f28df 9}
084caaf3 10
07dc8b03 11our $VERSION = '1.999_001';
20b853bb 12$VERSION = eval $VERSION;
07dc8b03 13$VERSION = 2; # a bit of a cheat, but requesting v2 needs to be possible
394c3a46 14
23c0b85d 15our @WARNING_CATEGORIES = grep { exists $warnings::Offsets{$_} } qw(
16 closure
17 deprecated
18 exiting
19 experimental
c5b35ddf 20 experimental::autoderef
1e139b49 21 experimental::const_attr
23c0b85d 22 experimental::lexical_subs
23 experimental::lexical_topic
c5b35ddf 24 experimental::postderef
1e139b49 25 experimental::re_strict
26 experimental::refaliasing
23c0b85d 27 experimental::regex_sets
c5b35ddf 28 experimental::signatures
23c0b85d 29 experimental::smartmatch
1e139b49 30 experimental::win32_perlio
23c0b85d 31 glob
32 imprecision
33 io
34 closed
35 exec
36 layer
37 newline
38 pipe
c5b35ddf 39 syscalls
23c0b85d 40 unopened
1e139b49 41 locale
23c0b85d 42 misc
1e139b49 43 missing
23c0b85d 44 numeric
45 once
46 overflow
47 pack
48 portable
49 recursion
50 redefine
1e139b49 51 redundant
23c0b85d 52 regexp
53 severe
54 debugging
55 inplace
56 internal
57 malloc
58 signal
59 substr
60 syntax
61 ambiguous
62 bareword
63 digit
64 illegalproto
65 parenthesis
66 precedence
67 printf
68 prototype
69 qw
70 reserved
71 semicolon
72 taint
73 threads
74 uninitialized
75 unpack
76 untie
77 utf8
78 non_unicode
79 nonchar
80 surrogate
81 void
1e139b49 82 void_unusual
23c0b85d 83 y2k
84);
85
394c3a46 86sub VERSION {
24590d98 87 {
88 no warnings;
89 local $@;
90 if (defined $_[1] && eval { &UNIVERSAL::VERSION; 1}) {
91 $^H |= 0x20000
92 unless _PERL_LT_5_8_4;
93 $^H{strictures_enable} = int $_[1];
94 }
394c3a46 95 }
24590d98 96 _CAN_GOTO_VERSION ? goto &UNIVERSAL::VERSION : &UNIVERSAL::VERSION;
394c3a46 97}
98
8f0df510 99our %extra_load_states;
ffedb166 100
2da53f4a 101our $Smells_Like_VCS;
12b8f19b 102
394c3a46 103sub import {
92cde693 104 my $class = shift;
105 my %opts = ref $_[0] ? %{$_[0]} : @_;
106 if (!exists $opts{version}) {
107 $opts{version}
108 = exists $^H{strictures_enable} ? delete $^H{strictures_enable}
109 : int $VERSION;
110 }
c5a67be6 111 $opts{file} = (caller)[1];
92cde693 112 $class->_enable(\%opts);
113}
114
115sub _enable {
116 my ($class, $opts) = @_;
117 my $version = $opts->{version};
118 $version = 'undef'
119 if !defined $version;
120 my $method = "_enable_$version";
121 if (!$class->can($method)) {
a97f64c7 122 require Carp;
123 Carp::croak("Major version specified as $version - not supported!");
92cde693 124 }
125 $class->$method($opts);
126}
127
128sub _enable_1 {
c5a67be6 129 my ($class, $opts) = @_;
394c3a46 130 strict->import;
131 warnings->import(FATAL => 'all');
084caaf3 132
c5a67be6 133 if (_want_extra($opts->{file})) {
134 _load_extras(qw(indirect multidimensional bareword::filehandles));
135 indirect->unimport(':fatal')
136 if $extra_load_states{indirect};
137 multidimensional->unimport
138 if $extra_load_states{multidimensional};
139 bareword::filehandles->unimport
140 if $extra_load_states{'bareword::filehandles'};
141 }
8f0df510 142}
143
1931c77d 144our @V2_NONFATAL = grep { exists $warnings::Offsets{$_} } (
145 'exec', # not safe to catch
146 'recursion', # will be caught by other mechanisms
147 'internal', # not safe to catch
148 'malloc', # not safe to catch
149 'newline', # stat on nonexistent file with a newline in it
150 'experimental', # no reason for these to be fatal
151 'deprecated', # unfortunately can't make these fatal
152 'portable', # everything worked fine here, just may not elsewhere
23c0b85d 153);
1931c77d 154our @V2_DISABLE = grep { exists $warnings::Offsets{$_} } (
155 'once' # triggers inconsistently, can't be fatalized
23c0b85d 156);
157
158sub _enable_2 {
159 my ($class, $opts) = @_;
160 strict->import;
161 warnings->import;
162 warnings->import(FATAL => @WARNING_CATEGORIES);
d50343b9 163 warnings->unimport(FATAL => @V2_NONFATAL);
164 warnings->import(@V2_NONFATAL);
23c0b85d 165 warnings->unimport(@V2_DISABLE);
166
167 if (_want_extra($opts->{file})) {
168 _load_extras(qw(indirect multidimensional bareword::filehandles));
169 indirect->unimport(':fatal')
170 if $extra_load_states{indirect};
171 multidimensional->unimport
172 if $extra_load_states{multidimensional};
173 bareword::filehandles->unimport
174 if $extra_load_states{'bareword::filehandles'};
175 }
176}
177
9d763997 178sub _want_extra_env {
c5a67be6 179 if (exists $ENV{PERL_STRICTURES_EXTRA}) {
180 if (_PERL_LT_5_8_4 and $ENV{PERL_STRICTURES_EXTRA}) {
181 die 'PERL_STRICTURES_EXTRA checks are not available on perls older'
182 . "than 5.8.4: please unset \$ENV{PERL_STRICTURES_EXTRA}\n";
394c3a46 183 }
9d763997 184 return $ENV{PERL_STRICTURES_EXTRA} ? 1 : 0;
c5a67be6 185 }
9d763997 186 return undef;
187}
188
189sub _want_extra {
190 my $file = shift;
191 my $want_env = _want_extra_env();
192 return $want_env
193 if defined $want_env;
c5a67be6 194 return (
195 !_PERL_LT_5_8_4
196 and $file =~ /^(?:t|xt|lib|blib)[\\\/]/
197 and defined $Smells_Like_VCS ? $Smells_Like_VCS
198 : ( $Smells_Like_VCS = !!(
199 -e '.git' || -e '.svn' || -e '.hg'
200 || (-e '../../dist.ini'
201 && (-e '../../.git' || -e '../../.svn' || -e '../../.hg' ))
202 ))
203 );
204}
4f219885 205
c5a67be6 206sub _load_extras {
207 my @extras = @_;
8f0df510 208 my @failed;
209 foreach my $mod (@extras) {
210 next
211 if exists $extra_load_states{$mod};
4f219885 212
8f0df510 213 $extra_load_states{$mod} = eval "require $mod; 1;" or do {
214 push @failed, $mod;
488f2966 215
8f0df510 216 #work around 5.8 require bug
217 (my $file = $mod) =~ s|::|/|g;
218 delete $INC{"${file}.pm"};
219 };
220 }
4f219885 221
8f0df510 222 if (@failed) {
223 my $failed = join ' ', @failed;
224 my $extras = join ' ', @extras;
225 print STDERR <<EOE;
ffedb166 226strictures.pm extra testing active but couldn't load all modules. Missing were:
227
228 $failed
229
0925b84b 230Extra testing is auto-enabled in checkouts only, so if you're the author
624cf8bb 231of a strictures-using module you need to run:
653f4377 232
8f0df510 233 cpan $extras
653f4377 234
235but these modules are not required by your users.
084caaf3 236EOE
394c3a46 237 }
238}
239
2401;
241
242__END__
243=head1 NAME
244
245strictures - turn on strict and make all warnings fatal
246
247=head1 SYNOPSIS
248
1c35787c 249 use strictures 2;
394c3a46 250
251is equivalent to
252
253 use strict;
254 use warnings FATAL => 'all';
1c35787c 255 use warnings NONFATAL => qw(
256 exec
257 recursion
258 internal
259 malloc
260 newline
261 experimental
262 deprecated
263 portable
264 );
265 no warnings 'once';
394c3a46 266
5ab06a4d 267except when called from a file which matches:
394c3a46 268
5b2a026b 269 (caller)[1] =~ /^(?:t|xt|lib|blib)[\\\/]/
394c3a46 270
3e14202f 271and when either C<.git>, C<.svn>, or C<.hg> is present in the current directory
272(with the intention of only forcing extra tests on the author side) -- or when
273C<.git>, C<.svn>, or C<.hg> is present two directories up along with
274C<dist.ini> (which would indicate we are in a C<dzil test> operation, via
275L<Dist::Zilla>) -- or when the C<PERL_STRICTURES_EXTRA> environment variable is
40836ccc 276set, in which case it also does the equivalent of
394c3a46 277
394c3a46 278 no indirect 'fatal';
653f4377 279 no multidimensional;
280 no bareword::filehandles;
394c3a46 281
3e14202f 282Note that C<PERL_STRICTURES_EXTRA> may at some point add even more tests, with
283only a minor version increase, but any changes to the effect of C<use
284strictures> in normal mode will involve a major version bump.
394c3a46 285
0eb0d037 286If any of the extra testing modules are not present, L<strictures> will
25877bf2 287complain loudly, once, via C<warn()>, and then shut up. But you really
ffedb166 288should consider installing them, they're all great anti-footgun tools.
17b03f2e 289
394c3a46 290=head1 DESCRIPTION
291
292I've been writing the equivalent of this module at the top of my code for
293about a year now. I figured it was time to make it shorter.
294
25877bf2 295Things like the importer in C<use Moose> don't help me because they turn
d8c1c6b2 296warnings on but don't make them fatal -- which from my point of view is
2288278f 297useless because I want an exception to tell me my code isn't warnings-clean.
394c3a46 298
299Any time I see a warning from my code, that indicates a mistake.
300
d8c1c6b2 301Any time my code encounters a mistake, I want a crash -- not spew to STDERR
394c3a46 302and then unknown (and probably undesired) subsequent behaviour.
303
304I also want to ensure that obvious coding mistakes, like indirect object
305syntax (and not so obvious mistakes that cause things to accidentally compile
306as such) get caught, but not at the cost of an XS dependency and not at the
307cost of blowing things up on another machine.
308
0eb0d037 309Therefore, L<strictures> turns on additional checking, but only when it thinks
2288278f 310it's running in a test file in a VCS checkout -- although if this causes
93ae637e 311undesired behaviour this can be overridden by setting the
25877bf2 312C<PERL_STRICTURES_EXTRA> environment variable.
394c3a46 313
314If additional useful author side checks come to mind, I'll add them to the
3e14202f 315C<PERL_STRICTURES_EXTRA> code path only -- this will result in a minor version
316increase (e.g. 1.000000 to 1.001000 (1.1.0) or similar). Any fixes only to the
317mechanism of this code will result in a sub-version increase (e.g. 1.000000 to
3181.000001 (1.0.1)).
394c3a46 319
d48424bd 320=head1 CATEGORY SELECTIONS
321
322strictures does not enable fatal warnings for all categories.
323
324=over 4
325
326=item exec
327
328Includes a warning that can cause your program to continue running
329unintentionally after an internal fork. Not safe to fatalize.
330
331=item recursion
332
333Infinite recursion will end up overflowing the stack eventually anyway.
334
335=item internal
336
337Triggers deep within perl, in places that are not safe to trap.
338
339=item malloc
340
341Triggers deep within perl, in places that are not safe to trap.
342
343=item newline
344
345Includes a warning for using stat on a valid but suspect filename, ending in a
346newline.
347
348=item experimental
349
350Experimental features are used intentionally.
351
352=item deprecated
353
354Deprecations will inherently be added to in the future in unexpected ways,
355so making them fatal won't be reliable.
356
357=item portable
358
359Doesn't indicate an actual problem with the program, only that it may not
360behave properly if run on a different machine.
361
362=item once
363
364Can't be fatalized. Also triggers very inconsistently, so we just disable it.
365
366=back
367
1c35787c 368=head1 VERSIONS
369
370Depending on the version of strictures requested, different warnings will be
371enabled. If no specific version is requested, the current version's behavior
372will be used. Versions can be requested using perl's standard mechanism:
373
374 use strictures 2;
375
376Or, by passing in a C<version> option:
377
378 use strictures version => 2;
394c3a46 379
1c35787c 380=head2 VERSION 2
394c3a46 381
1c35787c 382Equivalent to:
383
384 use strict;
385 use warnings FATAL => 'all';
d771b3bb 386 use warnings NONFATAL => qw(
387 exec
388 recursion
389 internal
390 malloc
391 newline
392 experimental
393 deprecated
394 portable
395 );
396 no warnings 'once';
397
1c35787c 398 # and if in dev mode:
399 no indirect 'fatal';
400 no multidimensional;
401 no bareword::filehandles;
402
d771b3bb 403Additionally, any warnings created by modules using L<warnings::register> or
404C<warnings::register_categories()> will not be fatalized.
405
1c35787c 406=head2 VERSION 1
407
408Equivalent to:
409
410 use strict;
411 use warnings FATAL => 'all';
412 # and if in dev mode:
413 no indirect 'fatal';
414 no multidimensional;
415 no bareword::filehandles;
eae006ee 416
417=head1 METHODS
418
419=head2 import
420
1c35787c 421This method does the setup work described above in L</DESCRIPTION>. Optionally
422accepts a C<version> option to request a specific version's behavior.
eae006ee 423
424=head2 VERSION
425
25877bf2 426This method traps the C<< strictures->VERSION(1) >> call produced by a use line
eae006ee 427with a version number on it and does the version check.
428
f9df7e2e 429=head1 EXTRA TESTING RATIONALE
430
25877bf2 431Every so often, somebody complains that they're deploying via C<git pull>
d8c1c6b2 432and that they don't want L<strictures> to enable itself in this case -- and that
f9df7e2e 433setting C<PERL_STRICTURES_EXTRA> to 0 isn't acceptable (additional ways to
434disable extra testing would be welcome but the discussion never seems to get
435that far).
436
437In order to allow us to skip a couple of stages and get straight to a
438productive conversation, here's my current rationale for turning the
439extra testing on via a heuristic:
440
441The extra testing is all stuff that only ever blows up at compile time;
2288278f 442this is intentional. So the oft-raised concern that it's different code being
d8c1c6b2 443tested is only sort of the case -- none of the modules involved affect the
f9df7e2e 444final optree to my knowledge, so the author gets some additional compile
445time crashes which he/she then fixes, and the rest of the testing is
446completely valid for all environments.
447
d8c1c6b2 448The point of the extra testing -- especially C<no indirect> -- is to catch
f9df7e2e 449mistakes that newbie users won't even realise are mistakes without
450help. For example,
451
452 foo { ... };
453
d8c1c6b2 454where foo is an & prototyped sub that you forgot to import -- this is
9a363fed 455pernicious to track down since all I<seems> fine until it gets called
f9df7e2e 456and you get a crash. Worse still, you can fail to have imported it due
457to a circular require, at which point you have a load order dependent
9a363fed 458bug which I've seen before now I<only> show up in production due to tiny
f9df7e2e 459differences between the production and the development environment. I wrote
460L<http://shadow.cat/blog/matt-s-trout/indirect-but-still-fatal/> to explain
461this particular problem before L<strictures> itself existed.
462
2288278f 463As such, in my experience so far L<strictures>' extra testing has
9a363fed 464I<avoided> production versus development differences, not caused them.
f9df7e2e 465
0eb0d037 466Additionally, L<strictures>' policy is very much "try and provide as much
d8c1c6b2 467protection as possible for newbies -- who won't think about whether there's
468an option to turn on or not" -- so having only the environment variable
f9df7e2e 469is not sufficient to achieve that (I get to explain that you need to add
d8c1c6b2 470C<use strict> at least once a week on freenode #perl -- newbies sometimes
f9df7e2e 471completely skip steps because they don't understand that that step
472is important).
473
d8c1c6b2 474I make no claims that the heuristic is perfect -- it's already been evolved
f9df7e2e 475significantly over time, especially for 1.004 where we changed things to
0eb0d037 476ensure it only fires on files in your checkout (rather than L<strictures>-using
f9df7e2e 477modules you happened to have installed, which was just silly). However, I
478hope the above clarifies why a heuristic approach is not only necessary but
3e14202f 479desirable from a point of view of providing new users with as much safety as
480possible, and will allow any future discussion on the subject to focus on "how
481do we minimise annoyance to people deploying from checkouts intentionally".
f9df7e2e 482
96c8649b 483=head1 SEE ALSO
484
485=over 4
486
487=item *
488
489L<indirect>
490
491=item *
492
493L<multidimensional>
494
495=item *
496
497L<bareword::filehandles>
498
499=back
500
eae006ee 501=head1 COMMUNITY AND SUPPORT
502
503=head2 IRC channel
504
505irc.perl.org #toolchain
506
507(or bug 'mst' in query on there or freenode)
508
509=head2 Git repository
510
511Gitweb is on http://git.shadowcat.co.uk/ and the clone URL is:
512
513 git clone git://git.shadowcat.co.uk/p5sagit/strictures.git
514
91be28bc 515The web interface to the repository is at:
516
517 http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit/strictures.git
518
eae006ee 519=head1 AUTHOR
520
d81f898d 521mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
eae006ee 522
523=head1 CONTRIBUTORS
524
8190ff5b 525Karen Etheridge (cpan:ETHER) <ether@cpan.org>
eae006ee 526
04b4a35d 527Mithaldu - Christian Walde (cpan:MITHALDU) <walde.christian@gmail.com>
528
a79d1096 529haarg - Graham Knop (cpan:HAARG) <haarg@haarg.org>
530
eae006ee 531=head1 COPYRIGHT
532
533Copyright (c) 2010 the strictures L</AUTHOR> and L</CONTRIBUTORS>
534as listed above.
535
536=head1 LICENSE
537
538This library is free software and may be distributed under the same terms
539as perl itself.
540
541=cut