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