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