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