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