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.4
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 "<line>" or "<loc>" or
181 "<place>" or "<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, of course, use both in the same comment as well.
190
191 Checks and Assertions via Comments
192 "### require: BOOLEAN_EXPR"
193 "### assert: BOOLEAN_EXPR"
194 "### ensure: BOOLEAN_EXPR"
195 "### insist: BOOLEAN_EXPR"
196 These four are synonyms for the same behaviour. The comment
197 evaluates the expression in a boolean context. If the result is
198 true, nothing more is done. If the result is false, the comment
199 throws an exception listing the expression, the fact that it
200 failed, and the values of any variables used in the expression.
201
202 For example, given the following assertion:
203
204 ### require: $min < $result && $result < $max
205
206 if the expression evaluated false, the comment would die with the
207 following message:
208
209 ### $min < $result && $result < $max was not true at demo.pl line 86.
210 ### $min was: 7
211 ### $result was: 1000004
212 ### $max was: 99
213
214 "### check: BOOLEAN_EXPR"
215 "### confirm: BOOLEAN_EXPR"
216 "### verify: BOOLEAN_EXPR"
217 These three are synonyms for the same behaviour. The comment
218 evaluates the expression in a boolean context. If the result is
219 true, nothing more is done. If the result is false, the comment
220 prints a warning message listing the expression, the fact that it
221 failed, and the values of any variables used in the expression.
222
223 The effect is identical to that of the four assertions listed
224 earlier, except that "warn" is used instead of "die".
225
226 Progress Bars
227 You can put a smart comment on the same line as any of the following
228 types of Perl loop:
229
230 foreach my VAR ( LIST ) { ### Progressing... done
231
232 for my VAR ( LIST ) { ### Progressing... done
233
234 foreach ( LIST ) { ### Progressing... done
235
236 for ( LIST ) { ### Progressing... done
237
238 while (CONDITION) { ### Progressing... done
239
240 until (CONDITION) { ### Progressing... done
241
242 for (INIT; CONDITION; INCR) { ### Progressing... done
243
244 In each case, the module animates the comment, causing the dots to
245 extend from the left text, reaching the right text on the last
246 iteration. For "open ended" loops (like "while" and C-style "for"
247 loops), the dots will never reach the right text and their progress
248 slows down as the number of iterations increases.
249
250 For example, a smart comment like:
251
252 for (@candidates) { ### Evaluating... done
253
254 would be animated is the following sequence (which would appear
255 sequentially on a single line, rather than on consecutive lines):
256
257 Evaluating done
258
259 Evaluating...... done
260
261 Evaluating............. done
262
263 Evaluating................... done
264
265 Evaluating..........................done
266
267 The module animates the first sequence of three identical characters in
268 the comment, provided those characters are followed by a gap of at
269 least two whitespace characters. So you can specify different types of
270 progress bars. For example:
271
272 for (@candidates) { ### Evaluating::: done
273
274 or:
275
276 for (@candidates) { ### Evaluating=== done
277
278 or:
279
280 for (@candidates) { ### Evaluating||| done
281
282 If the characters to be animated are immediately followed by other non-
283 whitespace characters before the gap, then those other non-whitespace
284 characters are used as an "arrow head" or "leader" and are pushed right
285 by the growing progress bar. For example:
286
287 for (@candidates) { ### Evaluating===| done
288
289 would animate like so:
290
291 Evaluating| done
292
293 Evaluating=====| done
294
295 Evaluating============| done
296
297 Evaluating==================| done
298
299 Evaluating==========================done
300
301 If a percentage character ("%") appears anywhere in the comment, it is
302 replaced by the percentage completion. For example:
303
304 for (@candidates) { ### Evaluating [===| ] % done
305
306 animates like so:
307
308 Evaluating [| ] 0% done
309
310 Evaluating [===| ] 25% done
311
312 Evaluating [========| ] 50% done
313
314 Evaluating [============| ] 75% done
315
316 Evaluating [=================] 100% done
317
318 If the "%" is in the "arrow head" it moves with the progress bar. For
319 example:
320
321 for (@candidates) { ### Evaluating |===[%] |
322
323 would be aninated like so:
324
325 Evaluating |[0%] |
326
327 Evaluating |=[25%] |
328
329 Evaluating |========[50%] |
330
331 Evaluating |===============[75%] |
332
333 Evaluating |===========================|
334
335 For "open-ended" loops, the percentage completion is unknown, so the
336 module replaces each "%" with the current iteration count. For example:
337
338 while ($next ne $target) { ### Evaluating |===[%] |
339
340 would animate like so:
341
342 Evaluating |[0] |
343
344 Evaluating |=[2] |
345
346 Evaluating |==[3] |
347
348 Evaluating |===[5] |
349
350 Evaluating |====[7] |
351
352 Evaluating |=====[8] |
353
354 Evaluating |======[11] |
355
356 Note that the non-sequential numbering in the above example is a result
357 of the "hurry up and slow down" algorithm that prevents open-ended
358 loops from ever reaching the right-hand side.
359
360 As a special case, if the progress bar is drawn as two pairs of
361 identical brackets:
362
363 for (@candidates) { ### Evaluating: [][]
364
365 for (@candidates) { ### Evaluating: {}{}
366
367 for (@candidates) { ### Evaluating: ()()
368
369 for (@candidates) { ### Evaluating: <><>
370
371 Then the bar grows by repeating bracket pairs:
372
373 Evaluating: [
374
375 Evaluating: []
376
377 Evaluating: [][
378
379 Evaluating: [][]
380
381 Evaluating: [][][
382
383 etc.
384
385 Finally, progress bars don't have to have an animated component. They
386 can just report the loop's progress numerically:
387
388 for (@candidates) { ### Evaluating (% done)
389
390 which would animate (all of the same line):
391
392 Evaluating (0% done)
393
394 Evaluating (25% done)
395
396 Evaluating (50% done)
397
398 Evaluating (75% done)
399
400 Evaluating (100% done)
401
402 Time-Remaining Estimates
403 When a progress bar is used with a "for" loop, the module tracks how
404 long each iteration is taking and makes an estimate of how much time
405 will be required to complete the entire loop.
406
407 Normally this estimate is not shown, unless the estimate becomes large
408 enough to warrant informing the user. Specifically, the estimate will
409 be shown if, after five seconds, the time remaining exceeds ten
410 seconds. In other words, a time-remaining estimate is shown if the
411 module detects a "for" loop that is likely to take more than 15 seconds
412 in total. For example:
413
414 for (@seven_samurai) { ### Fighting: [||| ]
415 fight();
416 sleep 5;
417 }
418
419 would be animated like so:
420
421 Fighting: [ ]
422
423 Fighting: [|||| ]
424
425 Fighting: [||||||||| ] (about 20 seconds remaining)
426
427 Fighting: [|||||||||||||| ] (about 20 seconds remaining)
428
429 Fighting: [|||||||||||||||||| ] (about 10 seconds remaining)
430
431 Fighting: [||||||||||||||||||||||| ] (less than 10 seconds remaining)
432
433 Fighting: [|||||||||||||||||||||||||||]
434
435 The precision of the reported time-remaining estimate is deliberately
436 vague, mainly to prevent it being annoyingly wrong.
437
439 In a sense, everything this module does is a diagnostic. All comments
440 that print anything, print it to "STDERR".
441
442 However, the module itself has only one diagnostic:
443
444 "Incomprehensible arguments: %s in call to 'use Smart::Comments"
445 You loaded the module and passed it an argument that wasn't
446 three-or- more "#"'s. Arguments like '###', '####', '#####', etc.
447 are the only ones that the module accepts.
448
450 Smart::Comments can make use of an environment variable from your
451 shell: "Smart_Comments". This variable can be specified either with a
452 true/false value (i.e. 1 or 0) or with the same arguments as may be
453 passed on the "use" line when loading the module (see "INTERFACE").
454 The following table summarizes the behaviour:
455
456 Value of
457 $ENV{Smart_Comments} Equivalent Perl
458
459 1 use Smart::Comments;
460 0 no Smart::Comments;
461 '###:####' use Smart::Comments qw(### ####);
462 '### ####' use Smart::Comments qw(### ####);
463
464 To enable the "Smart_Comments" environment variable, you need to load
465 the module with the "-ENV" flag:
466
467 use Smart::Comments -ENV;
468
469 Note that you can still specify other arguments in the "use" statement:
470
471 use Smart::Comments -ENV, qw(### #####);
472
473 In this case, the contents of the environment variable replace the
474 "-ENV" in the argument list.
475
477 The module requires the following modules:
478
479 · Filter::Simple
480
481 · version.pm
482
483 · List::Util
484
485 · Data::Dumper
486
487 · Text::Balanced
488
490 None reported. This module is probably even relatively safe with other
491 Filter::Simple modules since it is very specific and limited in what it
492 filters.
493
495 No bugs have been reported.
496
497 This module has the usual limitations of source filters (i.e. it looks
498 smarter than it is).
499
500 Please report any bugs or feature requests to
501 "bug-smart-comments@rt.cpan.org", or through the web interface at
502 <http://rt.cpan.org>.
503
505 Damian Conway "<DCONWAY@cpan.org>"
506
508 Copyright (c) 2005, Damian Conway "<DCONWAY@cpan.org>". All rights
509 reserved.
510
511 This module is free software; you can redistribute it and/or modify it
512 under the same terms as Perl itself.
513
515 BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
516 FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT
517 WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
518 PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND,
519 EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
520 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
521 ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
522 YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
523 NECESSARY SERVICING, REPAIR, OR CORRECTION.
524
525 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
526 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
527 REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE
528 TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR
529 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
530 SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
531 RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
532 FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
533 SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
534 DAMAGES.
535
536
537
538perl v5.12.0 2009-09-04 Smart::Comments(3)