← Index
NYTProf Performance Profile   « line view »
For split.pl
  Run on Thu Apr 20 02:05:47 2023
Reported on Thu Apr 20 18:31:09 2023

Filename/home/hejohns/perl5/lib/perl5/Carp/Assert.pm
StatementsExecuted 42 statements in 743µs
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
111313µs512µsCarp::Assert::::BEGIN@8Carp::Assert::BEGIN@8
33325µs189µsCarp::Assert::::importCarp::Assert::import
31120µs162µsCarp::Assert::::_export_to_levelCarp::Assert::_export_to_level
11113µs1.09msCarp::Assert::::BEGIN@10Carp::Assert::BEGIN@10
11110µs15µsCarp::Assert::::BEGIN@4Carp::Assert::BEGIN@4
1114µs22µsCarp::Assert::::BEGIN@5Carp::Assert::BEGIN@5
1114µs13µsCarp::Assert::::BEGIN@6Carp::Assert::BEGIN@6
3112µs2µsCarp::Assert::::CORE:matchCarp::Assert::CORE:match (opcode)
0000s0sCarp::Assert::::_fail_msgCarp::Assert::_fail_msg
0000s0sCarp::Assert::::affirmCarp::Assert::affirm
0000s0sCarp::Assert::::assertCarp::Assert::assert
0000s0sCarp::Assert::::noopCarp::Assert::noop
0000s0sCarp::Assert::::noop_affirmCarp::Assert::noop_affirm
0000s0sCarp::Assert::::shouldCarp::Assert::should
0000s0sCarp::Assert::::shouldntCarp::Assert::shouldnt
0000s0sCarp::Assert::::unimportCarp::Assert::unimport
0000s0sshouldn::::t shouldn::t
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Carp::Assert;
2
318µsrequire 5.006;
4224µs220µ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
use strict qw(subs vars);
# spent 15µs making 1 call to Carp::Assert::BEGIN@4 # spent 5µs making 1 call to strict::import
5214µs241µ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
use warnings;
# spent 22µs making 1 call to Carp::Assert::BEGIN@5 # spent 18µs making 1 call to warnings::import
6217µs221µ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
use Exporter;
# spent 13µs making 1 call to Carp::Assert::BEGIN@6 # spent 9µs making 1 call to Exporter::import
7
82110µs2536µ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
use vars qw(@ISA $VERSION %EXPORT_TAGS);
# 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
BEGIN {
111200ns $VERSION = '0.21';
12
1316µs @ISA = qw(Exporter);
14
151900ns %EXPORT_TAGS = (
16 NDEBUG => [qw(assert affirm should shouldnt DEBUG)],
17 );
181400ns $EXPORT_TAGS{DEBUG} = $EXPORT_TAGS{NDEBUG};
1913µs11.07ms Exporter::export_tags(qw(NDEBUG DEBUG));
# spent 1.07ms making 1 call to Exporter::export_tags
201517µs11.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)
23sub REAL_DEBUG () { 1 } # CONSTANT
24sub 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
28sub noop { undef }
29sub 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
sub import {
32 my $env_ndebug = exists $ENV{PERL_NDEBUG} ? $ENV{PERL_NDEBUG}
3333µs : $ENV{'NDEBUG'};
34316µs32µ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 {
4633µs *DEBUG = *REAL_DEBUG;
4734µs3162µ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.
53sub _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
{
553800ns my $pkg = shift;
563800ns my $level = shift;
5731µs (undef) = shift; # XXX redundant arg
5832µs my $callpkg = caller($level);
59311µs329µs $pkg->export($callpkg, @_);
# spent 29µs making 3 calls to Exporter::export, avg 10µs/call
60}
61
62
63sub 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.
71sub _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
82Carp::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
116BEGIN {
117 local %ENV = %ENV;
118 delete @ENV{qw(PERL_NDEBUG NDEBUG)};
119 require Carp::Assert;
120 Carp::Assert->import;
121}
122
123local %ENV = %ENV;
124delete @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
132Carp::Assert is intended for a purpose like the ANSI C library
133L<assert.h|http://en.wikipedia.org/wiki/Assert.h>.
134If you're already familiar with assert.h, then you can
135probably skip this and go straight to the FUNCTIONS section.
136
137Assertions are the explicit expressions of your assumptions about the
138reality your program is expected to deal with, and a declaration of
139those which it is not. They are used to prevent your program from
140blissfully processing garbage inputs (garbage in, garbage out becomes
141garbage in, error out) and to tell you when you've produced garbage
142output. (If I was going to be a cynic about Perl and the user nature,
143I'd say there are no user inputs but garbage, and Perl produces
144nothing but...)
145
146An assertion is used to prevent the impossible from being asked of
147your 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
164is( my_sqrt(4), 2, 'my_sqrt example with good input' );
165ok( !eval{ my_sqrt(-1); 1 }, ' and pukes on bad' );
166
167The assertion will warn you if a negative number was handed to your
168subroutine, a reality the routine has no intention of dealing with.
169
170An assertion should also be used as something of a reality check, to
171make 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
180The assertion makes sure you have some @stuff at the end. Maybe the
181file was empty, maybe do_something() returned an empty list... either
182way, the assert() will give you a clue as to where the problem lies,
183rather than 50 lines down at when you wonder why your program isn't
184printing anything.
185
186Since assertions are designed for debugging and will remove themelves
187from production code, your assertions should be carefully crafted so
188as to not have any side-effects, change any variables, or otherwise
189have any effect on your program. Here is an example of a bad
190assertation:
191
192 assert($error = 1 if $king ne 'Henry'); # Bad!
193
194It sets an error flag which may then be used somewhere else in your
195program. When you shut off your assertions with the $DEBUG flag,
196$error will no longer be set.
197
198Here's another example of B<bad> use:
199
200 assert($next_pres ne 'Dan Quayle' or goto Canada); # Bad!
201
202This assertion has the side effect of moving to Canada should it fail.
203This is a very bad assertion since error handling should not be
204placed in an assertion, nor should it have side-effects.
205
206In short, an assertion is an executable comment. For instance, instead
207of writing this
208
209 # $life ends with a '!'
210 $life = begin_life();
211
212you'd replace the comment with an assertion which B<enforces> the comment.
213
214 $life = begin_life();
215 assert( $life =~ /!$/ );
216
217=for testing
218my $life = 'Whimper!';
219ok( 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
231assert's functionality is effected by compile time value of the DEBUG
232constant, controlled by saying C<use Carp::Assert> or C<no
233Carp::Assert>. In the former case, assert will function as below.
234Otherwise, the assert function will compile itself out of the program.
235See 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
244Give assert an expression, assert will Carp::confess() if that
245expression is false, otherwise it does nothing. (DO NOT use the
246return value of assert for anything, I mean it... really!).
247
248=for testing
249ok( eval { assert(1); 1 } );
250ok( !eval { assert(0); 1 } );
251
252The 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
259eval { assert(0) };
260like( $@, '/^Assertion failed!/', 'error format' );
261like( $@, '/Carp::Assert::assert\(0\) called at/', ' with stack trace' );
262
263Indicating that in the file "prog" an assert failed inside the
264function main::foo() on line 23 and that foo() was in turn called from
265line 50 in the same file.
266
267If given a $name, assert() will incorporate this into your error message,
268giving 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
274eval { assert( Dogs->isa('People'), 'Dogs are people, too!' ); };
275like( $@, '/^Assertion \(Dogs are people, too!\) failed!/', 'names' );
276
277=cut
278
279sub 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
293Very similar to assert(), but instead of taking just a simple
294expression it takes an entire block of code and evaluates it to make
295sure its true. This can allow more complicated assertions than
296assert() can without letting the debugging code leak out into
297production and without having to smash together several
298statements 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
311my $foo = 1; my $bar = 2;
312eval { affirm { $foo == $bar } };
313like( $@, '/\$foo == \$bar/' );
314
315
316affirm() also has the nice side effect that if you forgot the C<if DEBUG>
317suffix its arguments will not be evaluated at all. This can be nice
318if you stick affirm()s with expensive checks into hot loops and other
319time-sensitive parts of your program.
320
321If the $name is left off and your Perl version is 5.6 or higher the
322affirm() diagnostics will include the code begin affirmed.
323
324=cut
325
326sub 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
353Similar to assert(), it is specially for simple "this should be that"
354or "this should be anything but that" style of assertions.
355
356Due to Perl's lack of a good macro system, assert() can only report
357where something failed, but it can't report I<what> failed or I<how>.
358should() 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
364So this:
365
366 should($this, $that) if DEBUG;
367
368is similar to this:
369
370 assert($this eq $that) if DEBUG;
371
372except for the better error message.
373
374Currently, should() and shouldnt() can only do simple eq and ne tests
375(respectively). Future versions may allow regexes.
376
377=cut
378
379sub should ($$) {
380 unless($_[0] eq $_[1]) {
381 require Carp;
382 &Carp::confess( _fail_msg("'$_[0]' should be '$_[1]'!") );
383 }
384 return undef;
385}
386
387sub 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.
396sub 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
411Because assertions are extra code and because it is sometimes necessary to
412place them in 'hot' portions of your code where speed is paramount,
413Carp::Assert provides the option to remove its assert() calls from your
414program.
415
416So, we provide a way to force Perl to inline the switched off assert()
417routine, thereby removing almost all performance impact on your production
418code.
419
420 no Carp::Assert; # assertions are off.
421 assert(1==1) if DEBUG;
422
423DEBUG is a constant set to 0. Adding the 'if DEBUG' condition on your
424assert() call gives perl the cue to go ahead and remove assert() call from
425your 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
432If 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
439Another way to switch off all asserts, system wide, is to define the
440NDEBUG or the PERL_NDEBUG environment variable.
441
442You can safely leave out the "if DEBUG" part, but then your assert()
443function will always execute (and its arguments evaluated and time
444spent). To get around this, use affirm(). You still have the
445overhead of calling a function but at least its arguments will not be
446evaluated.
447
448
449=head1 Differences from ANSI C
450
451assert() is intended to act like the function from ANSI C fame.
452Unfortunately, due to Perl's lack of macros or strong inlining, it's not
453nearly as unobtrusive.
454
455Well, the obvious one is the "if DEBUG" part. This is cleanest way I could
456think of to cause each assert() call and its arguments to be removed from
457the program at compile-time, like the ANSI C macro does.
458
459Also, this version of assert does not report the statement which
460failed, just the line number and call frame via Carp::confess. You
461can't do C<assert('$a == $b')> because $a and $b will probably be
462lexical, and thus unavailable to assert(). But with Perl, unlike C,
463you always have the source to look through, so the need isn't as
464great.
465
466
467=head1 EFFICIENCY
468
469With C<no Carp::Assert> (or NDEBUG) and using the C<if DEBUG> suffixes
470on all your assertions, Carp::Assert has almost no impact on your
471production code. I say almost because it does still add some load-time
472to your code (I've tried to reduce this as much as possible).
473
474If you forget the C<if DEBUG> on an C<assert()>, C<should()> or
475C<shouldnt()>, its arguments are still evaluated and thus will impact
476your code. You'll also have the extra overhead of calling a
477subroutine (even if that subroutine does nothing).
478
479Forgetting the C<if DEBUG> on an C<affirm()> is not so bad. While you
480still have the overhead of calling a subroutine (one that does
481nothing) it will B<not> evaluate its code block and that can save
482a lot.
483
484Try to remember the B<if DEBUG>.
485
486
487=head1 ENVIRONMENT
488
489=over 4
490
491=item NDEBUG
492
493Defining NDEBUG switches off all assertions. It has the same effect
494as changing "use Carp::Assert" to "no Carp::Assert" but it effects all
495code.
496
497=item PERL_NDEBUG
498
499Same as NDEBUG and will override it. Its provided to give you
500something which won't conflict with any C programs you might be
501working 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
510The 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
515Since C<POSIX> exports way too much, you should be using it like that anyway.
516
517=head2 C<affirm> and C<$^S>
518
519affirm() mucks with the expression's caller and it is run in an eval
520so anything that checks $^S will be wrong.
521
522=head2 C<shouldn't>
523
524Yes, there is a C<shouldn't> routine. It mostly works, but you B<must>
525put the C<if DEBUG> after it.
526
527=head2 missing C<if DEBUG>
528
529It would be nice if we could warn about missing C<if DEBUG>.
530
531
532=head1 SEE ALSO
533
534L<assert.h|http://en.wikipedia.org/wiki/Assert.h> - the wikipedia
535page about C<assert.h>.
536
537L<Carp::Assert::More> provides a set of convenience functions
538that are wrappers around C<Carp::Assert>.
539
540L<Sub::Assert> provides support for subroutine pre- and post-conditions.
541The documentation says it's slow.
542
543L<PerlX::Assert> provides compile-time assertions, which are usually
544optimised away at compile time. Currently part of the L<Moops>
545distribution, but may get its own distribution sometime in 2014.
546
547L<Devel::Assert> also provides an C<assert> function, for Perl >= 5.8.1.
548
549L<assertions> provides an assertion mechanism for Perl >= 5.9.0.
550
551=head1 REPOSITORY
552
553L<https://github.com/schwern/Carp-Assert>
554
555=head1 COPYRIGHT
556
557Copyright 2001-2007 by Michael G Schwern E<lt>schwern@pobox.comE<gt>.
558
559This program is free software; you can redistribute it and/or
560modify it under the same terms as Perl itself.
561
562See F<http://dev.perl.org/licenses/>
563
564
565=head1 AUTHOR
566
567Michael G Schwern <schwern@pobox.com>
568
569=cut
570
57113µsreturn 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
sub Carp::Assert::CORE:match; # opcode