1Carp::Assert(3)       User Contributed Perl Documentation      Carp::Assert(3)
2
3
4

NAME

6       Carp::Assert - executable comments
7

SYNOPSIS

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

DESCRIPTION

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

FUNCTIONS

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

Debugging vs Production

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

Differences from ANSI C

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

EFFICIENCY

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

ENVIRONMENT

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

BUGS, CAVETS and other MUSINGS

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

SEE ALSO

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

AUTHOR

318       Michael G Schwern <schwern@pobox.com>
319
320
321
322perl v5.12.0                      2007-01-05                   Carp::Assert(3)
Impressum