Filename | /home/hejohns/perl5/lib/perl5/Carp/Assert.pm |
Statements | Executed 42 statements in 743µs |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 313µs | 512µs | BEGIN@8 | Carp::Assert::
3 | 3 | 3 | 25µs | 189µs | import | Carp::Assert::
3 | 1 | 1 | 20µs | 162µs | _export_to_level | Carp::Assert::
1 | 1 | 1 | 13µs | 1.09ms | BEGIN@10 | Carp::Assert::
1 | 1 | 1 | 10µs | 15µs | BEGIN@4 | Carp::Assert::
1 | 1 | 1 | 4µs | 22µs | BEGIN@5 | Carp::Assert::
1 | 1 | 1 | 4µs | 13µs | BEGIN@6 | Carp::Assert::
3 | 1 | 1 | 2µs | 2µs | CORE:match (opcode) | Carp::Assert::
0 | 0 | 0 | 0s | 0s | _fail_msg | Carp::Assert::
0 | 0 | 0 | 0s | 0s | affirm | Carp::Assert::
0 | 0 | 0 | 0s | 0s | assert | Carp::Assert::
0 | 0 | 0 | 0s | 0s | noop | Carp::Assert::
0 | 0 | 0 | 0s | 0s | noop_affirm | Carp::Assert::
0 | 0 | 0 | 0s | 0s | should | Carp::Assert::
0 | 0 | 0 | 0s | 0s | shouldnt | Carp::Assert::
0 | 0 | 0 | 0s | 0s | unimport | Carp::Assert::
0 | 0 | 0 | 0s | 0s | t | shouldn::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Carp::Assert; | ||||
2 | |||||
3 | 1 | 8µs | require 5.006; | ||
4 | 2 | 24µs | 2 | 20µs | # spent 15µs (10+5) within Carp::Assert::BEGIN@4 which was called:
# once (10µs+5µs) by main::BEGIN@12 at line 4 # spent 15µs making 1 call to Carp::Assert::BEGIN@4
# spent 5µs making 1 call to strict::import |
5 | 2 | 14µs | 2 | 41µs | # spent 22µs (4+18) within Carp::Assert::BEGIN@5 which was called:
# once (4µs+18µs) by main::BEGIN@12 at line 5 # spent 22µs making 1 call to Carp::Assert::BEGIN@5
# spent 18µs making 1 call to warnings::import |
6 | 2 | 17µs | 2 | 21µs | # spent 13µs (4+9) within Carp::Assert::BEGIN@6 which was called:
# once (4µs+9µs) by main::BEGIN@12 at line 6 # spent 13µs making 1 call to Carp::Assert::BEGIN@6
# spent 9µs making 1 call to Exporter::import |
7 | |||||
8 | 2 | 110µs | 2 | 536µs | # spent 512µs (313+199) within Carp::Assert::BEGIN@8 which was called:
# once (313µs+199µs) by main::BEGIN@12 at line 8 # spent 512µs making 1 call to Carp::Assert::BEGIN@8
# spent 24µs making 1 call to vars::import |
9 | |||||
10 | # spent 1.09ms (13µs+1.08) within Carp::Assert::BEGIN@10 which was called:
# once (13µs+1.08ms) by main::BEGIN@12 at line 20 | ||||
11 | 1 | 200ns | $VERSION = '0.21'; | ||
12 | |||||
13 | 1 | 6µs | @ISA = qw(Exporter); | ||
14 | |||||
15 | 1 | 900ns | %EXPORT_TAGS = ( | ||
16 | NDEBUG => [qw(assert affirm should shouldnt DEBUG)], | ||||
17 | ); | ||||
18 | 1 | 400ns | $EXPORT_TAGS{DEBUG} = $EXPORT_TAGS{NDEBUG}; | ||
19 | 1 | 3µs | 1 | 1.07ms | Exporter::export_tags(qw(NDEBUG DEBUG)); # spent 1.07ms making 1 call to Exporter::export_tags |
20 | 1 | 517µs | 1 | 1.09ms | } # spent 1.09ms making 1 call to Carp::Assert::BEGIN@10 |
21 | |||||
22 | # constant.pm, alas, adds too much load time (yes, I benchmarked it) | ||||
23 | sub REAL_DEBUG () { 1 } # CONSTANT | ||||
24 | sub NDEBUG () { 0 } # CONSTANT | ||||
25 | |||||
26 | # Export the proper DEBUG flag according to if :NDEBUG is set. | ||||
27 | # Also export noop versions of our routines if NDEBUG | ||||
28 | sub noop { undef } | ||||
29 | sub noop_affirm (&;$) { undef }; | ||||
30 | |||||
31 | # spent 189µs (25+164) within Carp::Assert::import which was called 3 times, avg 63µs/call:
# once (9µs+59µs) by Gradescope::Translate::BEGIN@16 at line 16 of /home/hejohns/documentsNoSync/22f/490/gradescope-utils/lib/Gradescope/Translate.pm
# once (9µs+57µs) by main::BEGIN@12 at line 12 of /home/hejohns/documentsNoSync/22f/490/gradescope-utils/bin/split.pl
# once (6µs+49µs) by Gradescope::Color::BEGIN@16 at line 16 of /home/hejohns/documentsNoSync/22f/490/gradescope-utils/lib/Gradescope/Color.pm | ||||
32 | my $env_ndebug = exists $ENV{PERL_NDEBUG} ? $ENV{PERL_NDEBUG} | ||||
33 | 3 | 3µs | : $ENV{'NDEBUG'}; | ||
34 | 3 | 16µs | 3 | 2µs | if( grep(/^:NDEBUG$/, @_) or $env_ndebug ) { # spent 2µs making 3 calls to Carp::Assert::CORE:match, avg 533ns/call |
35 | my $caller = caller; | ||||
36 | foreach my $func (grep !/^DEBUG$/, @{$EXPORT_TAGS{'NDEBUG'}}) { | ||||
37 | if( $func eq 'affirm' ) { | ||||
38 | *{$caller.'::'.$func} = \&noop_affirm; | ||||
39 | } else { | ||||
40 | *{$caller.'::'.$func} = \&noop; | ||||
41 | } | ||||
42 | } | ||||
43 | *{$caller.'::DEBUG'} = \&NDEBUG; | ||||
44 | } | ||||
45 | else { | ||||
46 | 3 | 3µs | *DEBUG = *REAL_DEBUG; | ||
47 | 3 | 4µs | 3 | 162µs | Carp::Assert->_export_to_level(1, @_); # spent 162µs making 3 calls to Carp::Assert::_export_to_level, avg 54µs/call |
48 | } | ||||
49 | } | ||||
50 | |||||
51 | |||||
52 | # 5.004's Exporter doesn't have export_to_level. | ||||
53 | sub _export_to_level | ||||
54 | # spent 162µs (20+142) within Carp::Assert::_export_to_level which was called 3 times, avg 54µs/call:
# 3 times (20µs+142µs) by Carp::Assert::import at line 47, avg 54µs/call | ||||
55 | 3 | 800ns | my $pkg = shift; | ||
56 | 3 | 800ns | my $level = shift; | ||
57 | 3 | 1µs | (undef) = shift; # XXX redundant arg | ||
58 | 3 | 2µs | my $callpkg = caller($level); | ||
59 | 3 | 11µs | 3 | 29µs | $pkg->export($callpkg, @_); # spent 29µs making 3 calls to Exporter::export, avg 10µs/call |
60 | } | ||||
61 | |||||
62 | |||||
63 | sub unimport { | ||||
64 | *DEBUG = *NDEBUG; | ||||
65 | push @_, ':NDEBUG'; | ||||
66 | goto &import; | ||||
67 | } | ||||
68 | |||||
69 | |||||
70 | # Can't call confess() here or the stack trace will be wrong. | ||||
71 | sub _fail_msg { | ||||
72 | my($name) = shift; | ||||
73 | my $msg = 'Assertion'; | ||||
74 | $msg .= " ($name)" if defined $name; | ||||
75 | $msg .= " failed!\n"; | ||||
76 | return $msg; | ||||
77 | } | ||||
78 | |||||
79 | |||||
80 | =head1 NAME | ||||
81 | |||||
82 | Carp::Assert - executable comments | ||||
83 | |||||
84 | =head1 SYNOPSIS | ||||
85 | |||||
86 | # Assertions are on. | ||||
87 | use Carp::Assert; | ||||
88 | |||||
89 | $next_sunrise_time = sunrise(); | ||||
90 | |||||
91 | # Assert that the sun must rise in the next 24 hours. | ||||
92 | assert(($next_sunrise_time - time) < 24*60*60) if DEBUG; | ||||
93 | |||||
94 | # Assert that your customer's primary credit card is active | ||||
95 | affirm { | ||||
96 | my @cards = @{$customer->credit_cards}; | ||||
97 | $cards[0]->is_active; | ||||
98 | }; | ||||
99 | |||||
100 | |||||
101 | # Assertions are off. | ||||
102 | no Carp::Assert; | ||||
103 | |||||
104 | $next_pres = divine_next_president(); | ||||
105 | |||||
106 | # Assert that if you predict Dan Quayle will be the next president | ||||
107 | # your crystal ball might need some polishing. However, since | ||||
108 | # assertions are off, IT COULD HAPPEN! | ||||
109 | shouldnt($next_pres, 'Dan Quayle') if DEBUG; | ||||
110 | |||||
111 | |||||
112 | =head1 DESCRIPTION | ||||
113 | |||||
114 | =begin testing | ||||
115 | |||||
116 | BEGIN { | ||||
117 | local %ENV = %ENV; | ||||
118 | delete @ENV{qw(PERL_NDEBUG NDEBUG)}; | ||||
119 | require Carp::Assert; | ||||
120 | Carp::Assert->import; | ||||
121 | } | ||||
122 | |||||
123 | local %ENV = %ENV; | ||||
124 | delete @ENV{qw(PERL_NDEBUG NDEBUG)}; | ||||
125 | |||||
126 | =end testing | ||||
127 | |||||
128 | "We are ready for any unforseen event that may or may not | ||||
129 | occur." | ||||
130 | - Dan Quayle | ||||
131 | |||||
132 | Carp::Assert is intended for a purpose like the ANSI C library | ||||
133 | L<assert.h|http://en.wikipedia.org/wiki/Assert.h>. | ||||
134 | If you're already familiar with assert.h, then you can | ||||
135 | probably skip this and go straight to the FUNCTIONS section. | ||||
136 | |||||
137 | Assertions are the explicit expressions of your assumptions about the | ||||
138 | reality your program is expected to deal with, and a declaration of | ||||
139 | those which it is not. They are used to prevent your program from | ||||
140 | blissfully processing garbage inputs (garbage in, garbage out becomes | ||||
141 | garbage in, error out) and to tell you when you've produced garbage | ||||
142 | output. (If I was going to be a cynic about Perl and the user nature, | ||||
143 | I'd say there are no user inputs but garbage, and Perl produces | ||||
144 | nothing but...) | ||||
145 | |||||
146 | An assertion is used to prevent the impossible from being asked of | ||||
147 | your code, or at least tell you when it does. For example: | ||||
148 | |||||
149 | =for example begin | ||||
150 | |||||
151 | # Take the square root of a number. | ||||
152 | sub my_sqrt { | ||||
153 | my($num) = shift; | ||||
154 | |||||
155 | # the square root of a negative number is imaginary. | ||||
156 | assert($num >= 0); | ||||
157 | |||||
158 | return sqrt $num; | ||||
159 | } | ||||
160 | |||||
161 | =for example end | ||||
162 | |||||
163 | =for example_testing | ||||
164 | is( my_sqrt(4), 2, 'my_sqrt example with good input' ); | ||||
165 | ok( !eval{ my_sqrt(-1); 1 }, ' and pukes on bad' ); | ||||
166 | |||||
167 | The assertion will warn you if a negative number was handed to your | ||||
168 | subroutine, a reality the routine has no intention of dealing with. | ||||
169 | |||||
170 | An assertion should also be used as something of a reality check, to | ||||
171 | make sure what your code just did really did happen: | ||||
172 | |||||
173 | open(FILE, $filename) || die $!; | ||||
174 | @stuff = <FILE>; | ||||
175 | @stuff = do_something(@stuff); | ||||
176 | |||||
177 | # I should have some stuff. | ||||
178 | assert(@stuff > 0); | ||||
179 | |||||
180 | The assertion makes sure you have some @stuff at the end. Maybe the | ||||
181 | file was empty, maybe do_something() returned an empty list... either | ||||
182 | way, the assert() will give you a clue as to where the problem lies, | ||||
183 | rather than 50 lines down at when you wonder why your program isn't | ||||
184 | printing anything. | ||||
185 | |||||
186 | Since assertions are designed for debugging and will remove themelves | ||||
187 | from production code, your assertions should be carefully crafted so | ||||
188 | as to not have any side-effects, change any variables, or otherwise | ||||
189 | have any effect on your program. Here is an example of a bad | ||||
190 | assertation: | ||||
191 | |||||
192 | assert($error = 1 if $king ne 'Henry'); # Bad! | ||||
193 | |||||
194 | It sets an error flag which may then be used somewhere else in your | ||||
195 | program. When you shut off your assertions with the $DEBUG flag, | ||||
196 | $error will no longer be set. | ||||
197 | |||||
198 | Here's another example of B<bad> use: | ||||
199 | |||||
200 | assert($next_pres ne 'Dan Quayle' or goto Canada); # Bad! | ||||
201 | |||||
202 | This assertion has the side effect of moving to Canada should it fail. | ||||
203 | This is a very bad assertion since error handling should not be | ||||
204 | placed in an assertion, nor should it have side-effects. | ||||
205 | |||||
206 | In short, an assertion is an executable comment. For instance, instead | ||||
207 | of writing this | ||||
208 | |||||
209 | # $life ends with a '!' | ||||
210 | $life = begin_life(); | ||||
211 | |||||
212 | you'd replace the comment with an assertion which B<enforces> the comment. | ||||
213 | |||||
214 | $life = begin_life(); | ||||
215 | assert( $life =~ /!$/ ); | ||||
216 | |||||
217 | =for testing | ||||
218 | my $life = 'Whimper!'; | ||||
219 | ok( eval { assert( $life =~ /!$/ ); 1 }, 'life ends with a bang' ); | ||||
220 | |||||
221 | |||||
222 | =head1 FUNCTIONS | ||||
223 | |||||
224 | =over 4 | ||||
225 | |||||
226 | =item B<assert> | ||||
227 | |||||
228 | assert(EXPR) if DEBUG; | ||||
229 | assert(EXPR, $name) if DEBUG; | ||||
230 | |||||
231 | assert's functionality is effected by compile time value of the DEBUG | ||||
232 | constant, controlled by saying C<use Carp::Assert> or C<no | ||||
233 | Carp::Assert>. In the former case, assert will function as below. | ||||
234 | Otherwise, the assert function will compile itself out of the program. | ||||
235 | See L<Debugging vs Production> for details. | ||||
236 | |||||
237 | =for testing | ||||
238 | { | ||||
239 | package Some::Other; | ||||
240 | no Carp::Assert; | ||||
241 | ::ok( eval { assert(0) if DEBUG; 1 } ); | ||||
242 | } | ||||
243 | |||||
244 | Give assert an expression, assert will Carp::confess() if that | ||||
245 | expression is false, otherwise it does nothing. (DO NOT use the | ||||
246 | return value of assert for anything, I mean it... really!). | ||||
247 | |||||
248 | =for testing | ||||
249 | ok( eval { assert(1); 1 } ); | ||||
250 | ok( !eval { assert(0); 1 } ); | ||||
251 | |||||
252 | The error from assert will look something like this: | ||||
253 | |||||
254 | Assertion failed! | ||||
255 | Carp::Assert::assert(0) called at prog line 23 | ||||
256 | main::foo called at prog line 50 | ||||
257 | |||||
258 | =for testing | ||||
259 | eval { assert(0) }; | ||||
260 | like( $@, '/^Assertion failed!/', 'error format' ); | ||||
261 | like( $@, '/Carp::Assert::assert\(0\) called at/', ' with stack trace' ); | ||||
262 | |||||
263 | Indicating that in the file "prog" an assert failed inside the | ||||
264 | function main::foo() on line 23 and that foo() was in turn called from | ||||
265 | line 50 in the same file. | ||||
266 | |||||
267 | If given a $name, assert() will incorporate this into your error message, | ||||
268 | giving users something of a better idea what's going on. | ||||
269 | |||||
270 | assert( Dogs->isa('People'), 'Dogs are people, too!' ) if DEBUG; | ||||
271 | # Result - "Assertion (Dogs are people, too!) failed!" | ||||
272 | |||||
273 | =for testing | ||||
274 | eval { assert( Dogs->isa('People'), 'Dogs are people, too!' ); }; | ||||
275 | like( $@, '/^Assertion \(Dogs are people, too!\) failed!/', 'names' ); | ||||
276 | |||||
277 | =cut | ||||
278 | |||||
279 | sub assert ($;$) { | ||||
280 | unless($_[0]) { | ||||
281 | require Carp; | ||||
282 | Carp::confess( _fail_msg($_[1]) ); | ||||
283 | } | ||||
284 | return undef; | ||||
285 | } | ||||
286 | |||||
287 | |||||
288 | =item B<affirm> | ||||
289 | |||||
290 | affirm BLOCK if DEBUG; | ||||
291 | affirm BLOCK $name if DEBUG; | ||||
292 | |||||
293 | Very similar to assert(), but instead of taking just a simple | ||||
294 | expression it takes an entire block of code and evaluates it to make | ||||
295 | sure its true. This can allow more complicated assertions than | ||||
296 | assert() can without letting the debugging code leak out into | ||||
297 | production and without having to smash together several | ||||
298 | statements into one. | ||||
299 | |||||
300 | =for example begin | ||||
301 | |||||
302 | affirm { | ||||
303 | my $customer = Customer->new($customerid); | ||||
304 | my @cards = $customer->credit_cards; | ||||
305 | grep { $_->is_active } @cards; | ||||
306 | } "Our customer has an active credit card"; | ||||
307 | |||||
308 | =for example end | ||||
309 | |||||
310 | =for testing | ||||
311 | my $foo = 1; my $bar = 2; | ||||
312 | eval { affirm { $foo == $bar } }; | ||||
313 | like( $@, '/\$foo == \$bar/' ); | ||||
314 | |||||
315 | |||||
316 | affirm() also has the nice side effect that if you forgot the C<if DEBUG> | ||||
317 | suffix its arguments will not be evaluated at all. This can be nice | ||||
318 | if you stick affirm()s with expensive checks into hot loops and other | ||||
319 | time-sensitive parts of your program. | ||||
320 | |||||
321 | If the $name is left off and your Perl version is 5.6 or higher the | ||||
322 | affirm() diagnostics will include the code begin affirmed. | ||||
323 | |||||
324 | =cut | ||||
325 | |||||
326 | sub affirm (&;$) { | ||||
327 | unless( eval { &{$_[0]}; } ) { | ||||
328 | my $name = $_[1]; | ||||
329 | |||||
330 | if( !defined $name ) { | ||||
331 | eval { | ||||
332 | require B::Deparse; | ||||
333 | $name = B::Deparse->new->coderef2text($_[0]); | ||||
334 | }; | ||||
335 | $name = | ||||
336 | 'code display non-functional on this version of Perl, sorry' | ||||
337 | if $@; | ||||
338 | } | ||||
339 | |||||
340 | require Carp; | ||||
341 | Carp::confess( _fail_msg($name) ); | ||||
342 | } | ||||
343 | return undef; | ||||
344 | } | ||||
345 | |||||
346 | =item B<should> | ||||
347 | |||||
348 | =item B<shouldnt> | ||||
349 | |||||
350 | should ($this, $shouldbe) if DEBUG; | ||||
351 | shouldnt($this, $shouldntbe) if DEBUG; | ||||
352 | |||||
353 | Similar to assert(), it is specially for simple "this should be that" | ||||
354 | or "this should be anything but that" style of assertions. | ||||
355 | |||||
356 | Due to Perl's lack of a good macro system, assert() can only report | ||||
357 | where something failed, but it can't report I<what> failed or I<how>. | ||||
358 | should() and shouldnt() can produce more informative error messages: | ||||
359 | |||||
360 | Assertion ('this' should be 'that'!) failed! | ||||
361 | Carp::Assert::should('this', 'that') called at moof line 29 | ||||
362 | main::foo() called at moof line 58 | ||||
363 | |||||
364 | So this: | ||||
365 | |||||
366 | should($this, $that) if DEBUG; | ||||
367 | |||||
368 | is similar to this: | ||||
369 | |||||
370 | assert($this eq $that) if DEBUG; | ||||
371 | |||||
372 | except for the better error message. | ||||
373 | |||||
374 | Currently, should() and shouldnt() can only do simple eq and ne tests | ||||
375 | (respectively). Future versions may allow regexes. | ||||
376 | |||||
377 | =cut | ||||
378 | |||||
379 | sub should ($$) { | ||||
380 | unless($_[0] eq $_[1]) { | ||||
381 | require Carp; | ||||
382 | &Carp::confess( _fail_msg("'$_[0]' should be '$_[1]'!") ); | ||||
383 | } | ||||
384 | return undef; | ||||
385 | } | ||||
386 | |||||
387 | sub shouldnt ($$) { | ||||
388 | unless($_[0] ne $_[1]) { | ||||
389 | require Carp; | ||||
390 | &Carp::confess( _fail_msg("'$_[0]' shouldn't be that!") ); | ||||
391 | } | ||||
392 | return undef; | ||||
393 | } | ||||
394 | |||||
395 | # Sorry, I couldn't resist. | ||||
396 | sub shouldn't ($$) { # emacs cperl-mode madness #' sub { | ||||
397 | my $env_ndebug = exists $ENV{PERL_NDEBUG} ? $ENV{PERL_NDEBUG} | ||||
398 | : $ENV{'NDEBUG'}; | ||||
399 | if( $env_ndebug ) { | ||||
400 | return undef; | ||||
401 | } | ||||
402 | else { | ||||
403 | shouldnt($_[0], $_[1]); | ||||
404 | } | ||||
405 | } | ||||
406 | |||||
407 | =back | ||||
408 | |||||
409 | =head1 Debugging vs Production | ||||
410 | |||||
411 | Because assertions are extra code and because it is sometimes necessary to | ||||
412 | place them in 'hot' portions of your code where speed is paramount, | ||||
413 | Carp::Assert provides the option to remove its assert() calls from your | ||||
414 | program. | ||||
415 | |||||
416 | So, we provide a way to force Perl to inline the switched off assert() | ||||
417 | routine, thereby removing almost all performance impact on your production | ||||
418 | code. | ||||
419 | |||||
420 | no Carp::Assert; # assertions are off. | ||||
421 | assert(1==1) if DEBUG; | ||||
422 | |||||
423 | DEBUG is a constant set to 0. Adding the 'if DEBUG' condition on your | ||||
424 | assert() call gives perl the cue to go ahead and remove assert() call from | ||||
425 | your program entirely, since the if conditional will always be false. | ||||
426 | |||||
427 | # With C<no Carp::Assert> the assert() has no impact. | ||||
428 | for (1..100) { | ||||
429 | assert( do_some_really_time_consuming_check ) if DEBUG; | ||||
430 | } | ||||
431 | |||||
432 | If C<if DEBUG> gets too annoying, you can always use affirm(). | ||||
433 | |||||
434 | # Once again, affirm() has (almost) no impact with C<no Carp::Assert> | ||||
435 | for (1..100) { | ||||
436 | affirm { do_some_really_time_consuming_check }; | ||||
437 | } | ||||
438 | |||||
439 | Another way to switch off all asserts, system wide, is to define the | ||||
440 | NDEBUG or the PERL_NDEBUG environment variable. | ||||
441 | |||||
442 | You can safely leave out the "if DEBUG" part, but then your assert() | ||||
443 | function will always execute (and its arguments evaluated and time | ||||
444 | spent). To get around this, use affirm(). You still have the | ||||
445 | overhead of calling a function but at least its arguments will not be | ||||
446 | evaluated. | ||||
447 | |||||
448 | |||||
449 | =head1 Differences from ANSI C | ||||
450 | |||||
451 | assert() is intended to act like the function from ANSI C fame. | ||||
452 | Unfortunately, due to Perl's lack of macros or strong inlining, it's not | ||||
453 | nearly as unobtrusive. | ||||
454 | |||||
455 | Well, the obvious one is the "if DEBUG" part. This is cleanest way I could | ||||
456 | think of to cause each assert() call and its arguments to be removed from | ||||
457 | the program at compile-time, like the ANSI C macro does. | ||||
458 | |||||
459 | Also, this version of assert does not report the statement which | ||||
460 | failed, just the line number and call frame via Carp::confess. You | ||||
461 | can't do C<assert('$a == $b')> because $a and $b will probably be | ||||
462 | lexical, and thus unavailable to assert(). But with Perl, unlike C, | ||||
463 | you always have the source to look through, so the need isn't as | ||||
464 | great. | ||||
465 | |||||
466 | |||||
467 | =head1 EFFICIENCY | ||||
468 | |||||
469 | With C<no Carp::Assert> (or NDEBUG) and using the C<if DEBUG> suffixes | ||||
470 | on all your assertions, Carp::Assert has almost no impact on your | ||||
471 | production code. I say almost because it does still add some load-time | ||||
472 | to your code (I've tried to reduce this as much as possible). | ||||
473 | |||||
474 | If you forget the C<if DEBUG> on an C<assert()>, C<should()> or | ||||
475 | C<shouldnt()>, its arguments are still evaluated and thus will impact | ||||
476 | your code. You'll also have the extra overhead of calling a | ||||
477 | subroutine (even if that subroutine does nothing). | ||||
478 | |||||
479 | Forgetting the C<if DEBUG> on an C<affirm()> is not so bad. While you | ||||
480 | still have the overhead of calling a subroutine (one that does | ||||
481 | nothing) it will B<not> evaluate its code block and that can save | ||||
482 | a lot. | ||||
483 | |||||
484 | Try to remember the B<if DEBUG>. | ||||
485 | |||||
486 | |||||
487 | =head1 ENVIRONMENT | ||||
488 | |||||
489 | =over 4 | ||||
490 | |||||
491 | =item NDEBUG | ||||
492 | |||||
493 | Defining NDEBUG switches off all assertions. It has the same effect | ||||
494 | as changing "use Carp::Assert" to "no Carp::Assert" but it effects all | ||||
495 | code. | ||||
496 | |||||
497 | =item PERL_NDEBUG | ||||
498 | |||||
499 | Same as NDEBUG and will override it. Its provided to give you | ||||
500 | something which won't conflict with any C programs you might be | ||||
501 | working on at the same time. | ||||
502 | |||||
503 | =back | ||||
504 | |||||
505 | |||||
506 | =head1 BUGS, CAVETS and other MUSINGS | ||||
507 | |||||
508 | =head2 Conflicts with C<POSIX.pm> | ||||
509 | |||||
510 | The C<POSIX> module exports an C<assert> routine which will conflict with C<Carp::Assert> if both are used in the same namespace. If you are using both together, prevent C<POSIX> from exporting like so: | ||||
511 | |||||
512 | use POSIX (); | ||||
513 | use Carp::Assert; | ||||
514 | |||||
515 | Since C<POSIX> exports way too much, you should be using it like that anyway. | ||||
516 | |||||
517 | =head2 C<affirm> and C<$^S> | ||||
518 | |||||
519 | affirm() mucks with the expression's caller and it is run in an eval | ||||
520 | so anything that checks $^S will be wrong. | ||||
521 | |||||
522 | =head2 C<shouldn't> | ||||
523 | |||||
524 | Yes, there is a C<shouldn't> routine. It mostly works, but you B<must> | ||||
525 | put the C<if DEBUG> after it. | ||||
526 | |||||
527 | =head2 missing C<if DEBUG> | ||||
528 | |||||
529 | It would be nice if we could warn about missing C<if DEBUG>. | ||||
530 | |||||
531 | |||||
532 | =head1 SEE ALSO | ||||
533 | |||||
534 | L<assert.h|http://en.wikipedia.org/wiki/Assert.h> - the wikipedia | ||||
535 | page about C<assert.h>. | ||||
536 | |||||
537 | L<Carp::Assert::More> provides a set of convenience functions | ||||
538 | that are wrappers around C<Carp::Assert>. | ||||
539 | |||||
540 | L<Sub::Assert> provides support for subroutine pre- and post-conditions. | ||||
541 | The documentation says it's slow. | ||||
542 | |||||
543 | L<PerlX::Assert> provides compile-time assertions, which are usually | ||||
544 | optimised away at compile time. Currently part of the L<Moops> | ||||
545 | distribution, but may get its own distribution sometime in 2014. | ||||
546 | |||||
547 | L<Devel::Assert> also provides an C<assert> function, for Perl >= 5.8.1. | ||||
548 | |||||
549 | L<assertions> provides an assertion mechanism for Perl >= 5.9.0. | ||||
550 | |||||
551 | =head1 REPOSITORY | ||||
552 | |||||
553 | L<https://github.com/schwern/Carp-Assert> | ||||
554 | |||||
555 | =head1 COPYRIGHT | ||||
556 | |||||
557 | Copyright 2001-2007 by Michael G Schwern E<lt>schwern@pobox.comE<gt>. | ||||
558 | |||||
559 | This program is free software; you can redistribute it and/or | ||||
560 | modify it under the same terms as Perl itself. | ||||
561 | |||||
562 | See F<http://dev.perl.org/licenses/> | ||||
563 | |||||
564 | |||||
565 | =head1 AUTHOR | ||||
566 | |||||
567 | Michael G Schwern <schwern@pobox.com> | ||||
568 | |||||
569 | =cut | ||||
570 | |||||
571 | 1 | 3µs | return q|You don't just EAT the largest turnip in the world!|; | ||
# spent 2µs within Carp::Assert::CORE:match which was called 3 times, avg 533ns/call:
# 3 times (2µs+0s) by Carp::Assert::import at line 34, avg 533ns/call |