1Smart::Comments(3) User Contributed Perl Documentation Smart::Comments(3)
2
3
4
6 Smart::Comments - Comments that do more than just sit there
7
9 This document describes Smart::Comments version 1.000005
10
12 use Smart::Comments;
13
14 my $var = suspect_value();
15
16 ### $var
17
18 ### got: $var
19
20 ### Now computing value...
21
22 # and when looping:
23
24 for my $big_num (@big_nums) { ### Factoring... done
25 factor($big_num);
26 }
27
28 while ($error > $tolerance) { ### Refining---> done
29 refine_approximation()
30 }
31
32 for (my $i=0; $i<$MAX_INT; $i++) { ### Working===[%] done
33 do_something_expensive_with($i);
34 }
35
37 Smart comments provide an easy way to insert debugging and tracking
38 code into a program. They can report the value of a variable, track the
39 progress of a loop, and verify that particular assertions are true.
40
41 Best of all, when you're finished debugging, you don't have to remove
42 them. Simply commenting out the "use Smart::Comments" line turns them
43 back into regular comments. Leaving smart comments in your code is
44 smart because if you needed them once, you'll almost certainly need
45 them again later.
46
48 All smart comments start with three (or more) "#" characters. That is,
49 they are regular "#"-introduced comments whose first two (or more)
50 characters are also "#"'s.
51
52 Using the Module
53 The module is loaded like any other:
54
55 use Smart::Comments;
56
57 When loaded it filters the remaining code up to the next:
58
59 no Smart::Comments;
60
61 directive, replacing any smart comments with smart code that implements
62 the comments behaviour.
63
64 If you're debugging an application you can also invoke it with the
65 module from the command-line:
66
67 perl -MSmart::Comments $application.pl
68
69 Of course, this only enables smart comments in the application file
70 itself, not in any modules that the application loads.
71
72 You can also specify particular levels of smartness, by including one
73 or more markers as arguments to the "use":
74
75 use Smart::Comments '###', '####';
76
77 These arguments tell the module to filter only those comments that
78 start with the same number of "#"'s. So the above "use" statement would
79 "activate" any smart comments of the form:
80
81 ### Smart...
82
83 #### Smarter...
84
85 but not those of the form:
86
87 ##### Smartest...
88
89 This facility is useful for differentiating progress bars (see
90 "Progress Bars"), which should always be active, from debugging
91 comments (see "Debugging via Comments"), which should not:
92
93 #### Debugging here...
94
95 for (@values) { ### Progress: 0... 100
96 do_stuff();
97 }
98
99 Note that, for simplicity, all smart comments described below will be
100 written with three "#"'s; in all such cases, any number of "#"'s
101 greater than three could be used instead.
102
103 Debugging via Comments
104 The simplest way to use smart comments is for debugging. The module
105 supports the following forms, all of which print to "STDERR":
106
107 "### LABEL : EXPRESSION"
108 The LABEL is any sequence of characters up to the first colon. The
109 EXPRESSION is any valid Perl expression, including a simple
110 variable. When active, the comment prints the label, followed by
111 the value of the expression. For example:
112
113 ### Expected: 2 * $prediction
114 ### Got: $result
115
116 prints:
117
118 ### Expected: 42
119 ### Got: 13
120
121 "### EXPRESSION"
122 The EXPRESSION is any valid Perl expression, including a simple
123 variable. When active, the comment prints the expression, followed
124 by the value of the expression. For example:
125
126 ### 2 * $prediction
127 ### $result
128
129 prints:
130
131 ### 2 * $prediction: 42
132 ### $result: 13
133
134 "### TEXT..."
135 The TEXT is any sequence of characters that end in three dots.
136 When active, the comment just prints the text, including the dots.
137 For example:
138
139 ### Acquiring data...
140
141 $data = get_data();
142
143 ### Verifying data...
144
145 verify_data($data);
146
147 ### Assimilating data...
148
149 assimilate_data($data);
150
151 ### Tired now, having a little lie down...
152
153 sleep 900;
154
155 would print:
156
157 ### Acquiring data...
158
159 ### Verifying data...
160
161 ### Assimilating data...
162
163 ### Tired now, having a little lie down...
164
165 as each phase commenced. This is particularly useful for tracking
166 down precisely where a bug is occurring. It is also useful in non-
167 debugging situations, especially when batch processing, as a simple
168 progress feedback mechanism.
169
170 Within a textual smart comment you can use the special sequence
171 "<now>" (or "<time>" or "<when>") which is replaced with a
172 timestamp. For example:
173
174 ### [<now>] Acquiring data...
175
176 would produce something like:
177
178 ### [Fri Nov 18 15:11:15 EST 2005] Acquiring data...
179
180 There are also "spacestamps": "<here>" (or "<loc>" or "<place>" or
181 "<where>"):
182
183 ### Acquiring data at <loc>...
184
185 to produce something like:
186
187 ### Acquiring data at "demo.pl", line 7...
188
189 You can also request just the filename ("<file>") or just the line
190 number ("<line>") to get finer control over formatting:
191
192 ### Acquiring data at <file>[<line>]...
193
194 and produce something like:
195
196 ### Acquiring data at demo.pl[7]...
197
198 You can, of course, use any combination of stamps in the one
199 comment.
200
201 Checks and Assertions via Comments
202 "### require: BOOLEAN_EXPR"
203 "### assert: BOOLEAN_EXPR"
204 "### ensure: BOOLEAN_EXPR"
205 "### insist: BOOLEAN_EXPR"
206 These four are synonyms for the same behaviour. The comment
207 evaluates the expression in a boolean context. If the result is
208 true, nothing more is done. If the result is false, the comment
209 throws an exception listing the expression, the fact that it
210 failed, and the values of any variables used in the expression.
211
212 For example, given the following assertion:
213
214 ### require: $min < $result && $result < $max
215
216 if the expression evaluated false, the comment would die with the
217 following message:
218
219 ### $min < $result && $result < $max was not true at demo.pl line 86.
220 ### $min was: 7
221 ### $result was: 1000004
222 ### $max was: 99
223
224 "### check: BOOLEAN_EXPR"
225 "### confirm: BOOLEAN_EXPR"
226 "### verify: BOOLEAN_EXPR"
227 These three are synonyms for the same behaviour. The comment
228 evaluates the expression in a boolean context. If the result is
229 true, nothing more is done. If the result is false, the comment
230 prints a warning message listing the expression, the fact that it
231 failed, and the values of any variables used in the expression.
232
233 The effect is identical to that of the four assertions listed
234 earlier, except that "warn" is used instead of "die".
235
236 Progress Bars
237 You can put a smart comment on the same line as any of the following
238 types of Perl loop:
239
240 foreach my VAR ( LIST ) { ### Progressing... done
241
242 for my VAR ( LIST ) { ### Progressing... done
243
244 foreach ( LIST ) { ### Progressing... done
245
246 for ( LIST ) { ### Progressing... done
247
248 while (CONDITION) { ### Progressing... done
249
250 until (CONDITION) { ### Progressing... done
251
252 for (INIT; CONDITION; INCR) { ### Progressing... done
253
254 In each case, the module animates the comment, causing the dots to
255 extend from the left text, reaching the right text on the last
256 iteration. For "open ended" loops (like "while" and C-style "for"
257 loops), the dots will never reach the right text and their progress
258 slows down as the number of iterations increases.
259
260 For example, a smart comment like:
261
262 for (@candidates) { ### Evaluating... done
263
264 would be animated is the following sequence (which would appear
265 sequentially on a single line, rather than on consecutive lines):
266
267 Evaluating done
268
269 Evaluating...... done
270
271 Evaluating............. done
272
273 Evaluating................... done
274
275 Evaluating..........................done
276
277 The module animates the first sequence of three identical characters in
278 the comment, provided those characters are followed by a gap of at
279 least two whitespace characters. So you can specify different types of
280 progress bars. For example:
281
282 for (@candidates) { ### Evaluating::: done
283
284 or:
285
286 for (@candidates) { ### Evaluating=== done
287
288 or:
289
290 for (@candidates) { ### Evaluating||| done
291
292 If the characters to be animated are immediately followed by other non-
293 whitespace characters before the gap, then those other non-whitespace
294 characters are used as an "arrow head" or "leader" and are pushed right
295 by the growing progress bar. For example:
296
297 for (@candidates) { ### Evaluating===| done
298
299 would animate like so:
300
301 Evaluating| done
302
303 Evaluating=====| done
304
305 Evaluating============| done
306
307 Evaluating==================| done
308
309 Evaluating==========================done
310
311 If a percentage character ("%") appears anywhere in the comment, it is
312 replaced by the percentage completion. For example:
313
314 for (@candidates) { ### Evaluating [===| ] % done
315
316 animates like so:
317
318 Evaluating [| ] 0% done
319
320 Evaluating [===| ] 25% done
321
322 Evaluating [========| ] 50% done
323
324 Evaluating [============| ] 75% done
325
326 Evaluating [=================] 100% done
327
328 If the "%" is in the "arrow head" it moves with the progress bar. For
329 example:
330
331 for (@candidates) { ### Evaluating |===[%] |
332
333 would be animated like so:
334
335 Evaluating |[0%] |
336
337 Evaluating |=[25%] |
338
339 Evaluating |========[50%] |
340
341 Evaluating |===============[75%] |
342
343 Evaluating |===========================|
344
345 For "open-ended" loops, the percentage completion is unknown, so the
346 module replaces each "%" with the current iteration count. For example:
347
348 while ($next ne $target) { ### Evaluating |===[%] |
349
350 would animate like so:
351
352 Evaluating |[0] |
353
354 Evaluating |=[2] |
355
356 Evaluating |==[3] |
357
358 Evaluating |===[5] |
359
360 Evaluating |====[7] |
361
362 Evaluating |=====[8] |
363
364 Evaluating |======[11] |
365
366 Note that the non-sequential numbering in the above example is a result
367 of the "hurry up and slow down" algorithm that prevents open-ended
368 loops from ever reaching the right-hand side.
369
370 As a special case, if the progress bar is drawn as two pairs of
371 identical brackets:
372
373 for (@candidates) { ### Evaluating: [][]
374
375 for (@candidates) { ### Evaluating: {}{}
376
377 for (@candidates) { ### Evaluating: ()()
378
379 for (@candidates) { ### Evaluating: <><>
380
381 Then the bar grows by repeating bracket pairs:
382
383 Evaluating: [
384
385 Evaluating: []
386
387 Evaluating: [][
388
389 Evaluating: [][]
390
391 Evaluating: [][][
392
393 etc.
394
395 Finally, progress bars don't have to have an animated component. They
396 can just report the loop's progress numerically:
397
398 for (@candidates) { ### Evaluating (% done)
399
400 which would animate (all of the same line):
401
402 Evaluating (0% done)
403
404 Evaluating (25% done)
405
406 Evaluating (50% done)
407
408 Evaluating (75% done)
409
410 Evaluating (100% done)
411
412 Time-Remaining Estimates
413 When a progress bar is used with a "for" loop, the module tracks how
414 long each iteration is taking and makes an estimate of how much time
415 will be required to complete the entire loop.
416
417 Normally this estimate is not shown, unless the estimate becomes large
418 enough to warrant informing the user. Specifically, the estimate will
419 be shown if, after five seconds, the time remaining exceeds ten
420 seconds. In other words, a time-remaining estimate is shown if the
421 module detects a "for" loop that is likely to take more than 15 seconds
422 in total. For example:
423
424 for (@seven_samurai) { ### Fighting: [||| ]
425 fight();
426 sleep 5;
427 }
428
429 would be animated like so:
430
431 Fighting: [ ]
432
433 Fighting: [|||| ]
434
435 Fighting: [||||||||| ] (about 20 seconds remaining)
436
437 Fighting: [|||||||||||||| ] (about 20 seconds remaining)
438
439 Fighting: [|||||||||||||||||| ] (about 10 seconds remaining)
440
441 Fighting: [||||||||||||||||||||||| ] (less than 10 seconds remaining)
442
443 Fighting: [|||||||||||||||||||||||||||]
444
445 The precision of the reported time-remaining estimate is deliberately
446 vague, mainly to prevent it being annoyingly wrong.
447
449 In a sense, everything this module does is a diagnostic. All comments
450 that print anything, print it to "STDERR".
451
452 However, the module itself has only one diagnostic:
453
454 "Incomprehensible arguments: %s in call to 'use Smart::Comments"
455 You loaded the module and passed it an argument that wasn't
456 three-or- more "#"'s. Arguments like '###', '####', '#####', etc.
457 are the only ones that the module accepts.
458
460 Smart::Comments can make use of an environment variable from your
461 shell: "Smart_Comments". This variable can be specified either with a
462 true/false value (i.e. 1 or 0) or with the same arguments as may be
463 passed on the "use" line when loading the module (see "INTERFACE").
464 The following table summarizes the behaviour:
465
466 Value of
467 $ENV{Smart_Comments} Equivalent Perl
468
469 1 use Smart::Comments;
470 0 no Smart::Comments;
471 '###:####' use Smart::Comments qw(### ####);
472 '### ####' use Smart::Comments qw(### ####);
473
474 To enable the "Smart_Comments" environment variable, you need to load
475 the module with the "-ENV" flag:
476
477 use Smart::Comments -ENV;
478
479 Note that you can still specify other arguments in the "use" statement:
480
481 use Smart::Comments -ENV, qw(### #####);
482
483 In this case, the contents of the environment variable replace the
484 "-ENV" in the argument list.
485
487 The module requires the following modules:
488
489 • Filter::Simple
490
491 • version
492
493 • List::Util
494
495 • Data::Dumper
496
497 • Text::Balanced
498
500 None reported. This module is probably even relatively safe with other
501 Filter::Simple modules since it is very specific and limited in what it
502 filters.
503
505 No bugs have been reported.
506
507 This module has the usual limitations of source filters (i.e. it looks
508 smarter than it is).
509
510 Please report any bugs or feature requests to
511 "bug-smart-comments@rt.cpan.org", or through the web interface at
512 <http://rt.cpan.org>.
513
515 <https://github.com/neilb/Smart-Comments>
516
518 Damian Conway "<DCONWAY@cpan.org>"
519
521 Copyright (c) 2005, Damian Conway "<DCONWAY@cpan.org>". All rights
522 reserved.
523
524 This module is free software; you can redistribute it and/or modify it
525 under the same terms as Perl itself.
526
528 BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
529 FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT
530 WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
531 PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND,
532 EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
533 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
534 ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
535 YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
536 NECESSARY SERVICING, REPAIR, OR CORRECTION.
537
538 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
539 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
540 REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE
541 TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR
542 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
543 SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
544 RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
545 FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
546 SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
547 DAMAGES.
548
549
550
551perl v5.36.0 2023-01-20 Smart::Comments(3)