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