1Carp::Assert(3) User Contributed Perl Documentation Carp::Assert(3)
2
3
4
6 Carp::Assert - executable comments
7
9 # Assertions are on.
10 use Carp::Assert;
11
12 $next_sunrise_time = sunrise();
13
14 # Assert that the sun must rise in the next 24 hours.
15 assert(($next_sunrise_time - time) < 24*60*60) if DEBUG;
16
17 # Assert that your customer's primary credit card is active
18 affirm {
19 my @cards = @{$customer->credit_cards};
20 $cards[0]->is_active;
21 };
22
23 # Assertions are off.
24 no Carp::Assert;
25
26 $next_pres = divine_next_president();
27
28 # Assert that if you predict Dan Quayle will be the next president
29 # your crystal ball might need some polishing. However, since
30 # assertions are off, IT COULD HAPPEN!
31 shouldnt($next_pres, 'Dan Quayle') if DEBUG;
32
34 "We are ready for any unforseen event that may or may not
35 occur."
36 - Dan Quayle
37
38 Carp::Assert is intended for a purpose like the ANSI C library
39 assert.h. If you're already familiar with assert.h, then you can prob‐
40 ably skip this and go straight to the FUNCTIONS section.
41
42 Assertions are the explict expressions of your assumptions about the
43 reality your program is expected to deal with, and a declaration of
44 those which it is not. They are used to prevent your program from
45 blissfully processing garbage inputs (garbage in, garbage out becomes
46 garbage in, error out) and to tell you when you've produced garbage
47 output. (If I was going to be a cynic about Perl and the user nature,
48 I'd say there are no user inputs but garbage, and Perl produces nothing
49 but...)
50
51 An assertion is used to prevent the impossible from being asked of your
52 code, or at least tell you when it does. For example:
53
54 # Take the square root of a number.
55 sub my_sqrt {
56 my($num) = shift;
57
58 # the square root of a negative number is imaginary.
59 assert($num >= 0);
60
61 return sqrt $num;
62 }
63
64 The assertion will warn you if a negative number was handed to your
65 subroutine, a reality the routine has no intention of dealing with.
66
67 An assertion should also be used as something of a reality check, to
68 make sure what your code just did really did happen:
69
70 open(FILE, $filename) ⎪⎪ die $!;
71 @stuff = <FILE>;
72 @stuff = do_something(@stuff);
73
74 # I should have some stuff.
75 assert(@stuff > 0);
76
77 The assertion makes sure you have some @stuff at the end. Maybe the
78 file was empty, maybe do_something() returned an empty list... either
79 way, the assert() will give you a clue as to where the problem lies,
80 rather than 50 lines down at when you wonder why your program isn't
81 printing anything.
82
83 Since assertions are designed for debugging and will remove themelves
84 from production code, your assertions should be carefully crafted so as
85 to not have any side-effects, change any variables, or otherwise have
86 any effect on your program. Here is an example of a bad assertation:
87
88 assert($error = 1 if $king ne 'Henry'); # Bad!
89
90 It sets an error flag which may then be used somewhere else in your
91 program. When you shut off your assertions with the $DEBUG flag, $error
92 will no longer be set.
93
94 Here's another example of bad use:
95
96 assert($next_pres ne 'Dan Quayle' or goto Canada); # Bad!
97
98 This assertion has the side effect of moving to Canada should it fail.
99 This is a very bad assertion since error handling should not be placed
100 in an assertion, nor should it have side-effects.
101
102 In short, an assertion is an executable comment. For instance, instead
103 of writing this
104
105 # $life ends with a '!'
106 $life = begin_life();
107
108 you'd replace the comment with an assertion which enforces the comment.
109
110 $life = begin_life();
111 assert( $life =~ /!$/ );
112
114 assert
115 assert(EXPR) if DEBUG;
116 assert(EXPR, $name) if DEBUG;
117
118 assert's functionality is effected by compile time value of the
119 DEBUG constant, controlled by saying "use Carp::Assert" or "no
120 Carp::Assert". In the former case, assert will function as below.
121 Otherwise, the assert function will compile itself out of the pro‐
122 gram. See "Debugging vs Production" for details.
123
124 Give assert an expression, assert will Carp::confess() if that
125 expression is false, otherwise it does nothing. (DO NOT use the
126 return value of assert for anything, I mean it... really!).
127
128 The error from assert will look something like this:
129
130 Assertion failed!
131 Carp::Assert::assert(0) called at prog line 23
132 main::foo called at prog line 50
133
134 Indicating that in the file "prog" an assert failed inside the
135 function main::foo() on line 23 and that foo() was in turn called
136 from line 50 in the same file.
137
138 If given a $name, assert() will incorporate this into your error
139 message, giving users something of a better idea what's going on.
140
141 assert( Dogs->isa('People'), 'Dogs are people, too!' ) if DEBUG;
142 # Result - "Assertion (Dogs are people, too!) failed!"
143
144 affirm
145 affirm BLOCK if DEBUG;
146 affirm BLOCK $name if DEBUG;
147
148 Very similar to assert(), but instead of taking just a simple
149 expression it takes an entire block of code and evaluates it to
150 make sure its true. This can allow more complicated assertions
151 than assert() can without letting the debugging code leak out into
152 production and without having to smash together several statements
153 into one.
154
155 affirm {
156 my $customer = Customer->new($customerid);
157 my @cards = $customer->credit_cards;
158 grep { $_->is_active } @cards;
159 } "Our customer has an active credit card";
160
161 affirm() also has the nice side effect that if you forgot the "if
162 DEBUG" suffix its arguments will not be evaluated at all. This can
163 be nice if you stick affirm()s with expensive checks into hot loops
164 and other time-sensitive parts of your program.
165
166 If the $name is left off and your Perl version is 5.6 or higher the
167 affirm() diagnostics will include the code begin affirmed.
168
169 should
170 shouldnt
171 should ($this, $shouldbe) if DEBUG;
172 shouldnt($this, $shouldntbe) if DEBUG;
173
174 Similar to assert(), it is specially for simple "this should be
175 that" or "this should be anything but that" style of assertions.
176
177 Due to Perl's lack of a good macro system, assert() can only report
178 where something failed, but it can't report what failed or how.
179 should() and shouldnt() can produce more informative error mes‐
180 sages:
181
182 Assertion ('this' should be 'that'!) failed!
183 Carp::Assert::should('this', 'that') called at moof line 29
184 main::foo() called at moof line 58
185
186 So this:
187
188 should($this, $that) if DEBUG;
189
190 is similar to this:
191
192 assert($this eq $that) if DEBUG;
193
194 except for the better error message.
195
196 Currently, should() and shouldnt() can only do simple eq and ne
197 tests (respectively). Future versions may allow regexes.
198
200 Because assertions are extra code and because it is sometimes necessary
201 to place them in 'hot' portions of your code where speed is paramount,
202 Carp::Assert provides the option to remove its assert() calls from your
203 program.
204
205 So, we provide a way to force Perl to inline the switched off assert()
206 routine, thereby removing almost all performance impact on your produc‐
207 tion code.
208
209 no Carp::Assert; # assertions are off.
210 assert(1==1) if DEBUG;
211
212 DEBUG is a constant set to 0. Adding the 'if DEBUG' condition on your
213 assert() call gives perl the cue to go ahead and remove assert() call
214 from your program entirely, since the if conditional will always be
215 false.
216
217 # With C<no Carp::Assert> the assert() has no impact.
218 for (1..100) {
219 assert( do_some_really_time_consuming_check ) if DEBUG;
220 }
221
222 If "if DEBUG" gets too annoying, you can always use affirm().
223
224 # Once again, affirm() has (almost) no impact with C<no Carp::Assert>
225 for (1..100) {
226 affirm { do_some_really_time_consuming_check };
227 }
228
229 Another way to switch off all asserts, system wide, is to define the
230 NDEBUG or the PERL_NDEBUG environment variable.
231
232 You can safely leave out the "if DEBUG" part, but then your assert()
233 function will always execute (and its arguments evaluated and time
234 spent). To get around this, use affirm(). You still have the overhead
235 of calling a function but at least its arguments will not be evaluated.
236
238 assert() is intended to act like the function from ANSI C fame. Unfor‐
239 tunately, due to Perl's lack of macros or strong inlining, it's not
240 nearly as unobtrusive.
241
242 Well, the obvious one is the "if DEBUG" part. This is cleanest way I
243 could think of to cause each assert() call and its arguments to be
244 removed from the program at compile-time, like the ANSI C macro does.
245
246 Also, this version of assert does not report the statement which
247 failed, just the line number and call frame via Carp::confess. You
248 can't do "assert('$a == $b')" because $a and $b will probably be lexi‐
249 cal, and thus unavailable to assert(). But with Perl, unlike C, you
250 always have the source to look through, so the need isn't as great.
251
253 With "no Carp::Assert" (or NDEBUG) and using the "if DEBUG" suffixes on
254 all your assertions, Carp::Assert has almost no impact on your produc‐
255 tion code. I say almost because it does still add some load-time to
256 your code (I've tried to reduce this as much as possible).
257
258 If you forget the "if DEBUG" on an "assert()", "should()" or
259 "shouldnt()", its arguments are still evaluated and thus will impact
260 your code. You'll also have the extra overhead of calling a subroutine
261 (even if that subroutine does nothing).
262
263 Forgetting the "if DEBUG" on an "affirm()" is not so bad. While you
264 still have the overhead of calling a subroutine (one that does nothing)
265 it will not evaluate its code block and that can save alot.
266
267 Try to remember the if DEBUG.
268
270 NDEBUG
271 Defining NDEBUG switches off all assertions. It has the same
272 effect as changing "use Carp::Assert" to "no Carp::Assert" but it
273 effects all code.
274
275 PERL_NDEBUG
276 Same as NDEBUG and will override it. Its provided to give you
277 something which won't conflict with any C programs you might be
278 working on at the same time.
279
281 Conflicts with "POSIX.pm"
282
283 The "POSIX" module exports an "assert" routine which will conflict with
284 "Carp::Assert" if both are used in the same namespace. If you are
285 using both together, prevent "POSIX" from exporting like so:
286
287 use POSIX ();
288 use Carp::Assert;
289
290 Since "POSIX" exports way too much, you should be using it like that
291 anyway.
292
293 "affirm" and $^S
294
295 affirm() mucks with the expression's caller and it is run in an eval so
296 anything that checks $^S will be wrong.
297
298 "shouldn't"
299
300 Yes, there is a "shouldn't" routine. It mostly works, but you must put
301 the "if DEBUG" after it.
302
303 missing "if DEBUG"
304
305 It would be nice if we could warn about missing "if DEBUG".
306
308 assertions is a new module available in 5.9.0 which provides assertions
309 which can be enabled/disabled at compile time for real, no "if DEBUG"
310 necessary.
311
313 Copyright 2001-2007 by Michael G Schwern <schwern@pobox.com>.
314
315 This program is free software; you can redistribute it and/or modify it
316 under the same terms as Perl itself.
317
318 See http://dev.perl.org/licenses/
319
321 Michael G Schwern <schwern@pobox.com>
322
323
324
325perl v5.8.8 2007-01-04 Carp::Assert(3)