1Devel::Comments(3)    User Contributed Perl Documentation   Devel::Comments(3)
2
3
4

NAME

6       Devel::Comments - Debug with executable smart comments to logs
7

VERSION

9       This document describes Devel::Comments version 1.1.4
10

SYNOPSIS

12           use Devel::Comments;                    # acts just like Smart::Comments
13
14           # Dumps...
15           my $scalar      = 42;
16           ### $scalar                             # prints to STDERR:
17                                                   ### $my_scalar: 42
18
19           ### @array                              # dumps more complex
20           ### $HoHoA                              #   data structures, too
21
22           ### Just in the neighborhood            # prints literal message
23
24           # Level control...
25           use Devel::Comments '###';              # only activate level 3
26
27           ### $scalar                             # this prints
28           #### $scalar                            # this doesn't
29
30           # Output control...
31           use Devel::Comments *STDOUT;            # prints to STDOUT instead
32           use Devel::Comments \*FH;               # prints to some FH
33           use Devel::Comments $fh;                # prints to some $fh
34
35           use Devel::Comments ({                  # hashref calling syntax
36               -file           => 'my.log',            # opens my.log and prints to it
37           });
38
39           # Assertions...
40           my ($x, $y)     = 1, 0;
41           ### check  $x == $y                     # simulates warning and dumps info
42           ### insist $x == $y                     # dumps and dies
43
44           # Progress bars...
45           for my $i (0..1e6) {   ### Working===[%]     done
46               do_something_expensive_with($i);
47           }
48

DESCRIPTION

50       I get the feeling that the computer just skips over all the comments.
51           -- a grad student
52
53       Devel::Comments is a source filter for your Perl code, intended to be
54       used only during development. Specially-formatted 'smart' comments are
55       replaced by executable code to dump variables to screen or to file,
56       display loop progress bars, or enforce conditions. These smart comments
57       can all be disabled at once by commenting out the "use Devel::Comments"
58       line, whereupon they return to being simple, dumb comments. Your
59       debugging code can remain in place, guaranteed harmless, ready for the
60       next development cycle.
61
62       Devel::Comments is a fork of Smart::Comments; current intention is to
63       add new features without breaking backward compatibility.  Version
64       1.1.2 implements the 'any filehandle' feature, allowing smart output to
65       go to any filehandle opened for writing. You may instead pass in a
66       filename, which DC will open for you. Future plans include extended
67       calling syntax, numerical level enabling, improved progress bars, dump
68       method callback, and execution of arbitrary code.  Bugs raised against
69       Smart::Comments 1.0.4 will be fixed in DC.
70

INTERFACE

72       There are two main parts to the DC interface: arguments passed on the
73       "use" line; and 'smart' comments, which are specially-formatted
74       comments introduced by three or more octothorpes, such as '###',
75       '####', or even '########'.  Use-line arguments may also be passed in
76       an environment variable.
77
78       DC provides no run-time public variables, functions, routines, or
79       methods.  DC is a source filter and does its work at "compile-time".
80       (Some DC routines are called at run-time from within replacement code
81       previously filtered in.)
82
83   The Use Line
84       Most setup is done when the module is loaded via "use Devel::Comments".
85       If called with vanilla Smart::Comments arguments, DC will behave the
86       same; it's a drop-in replacement. Backwards compatibility to
87       Smart::Comments 1.0.4 is promised through DC 1.x.x.
88
89       Smart::Comments required arguments to be passed, in any order, as one
90       flat list. While this is convenient for a small number of restricted-
91       value arguments, it may "getcha" when attempted with many arguments
92       whose values are unrestricted. This "free-form" calling syntax does not
93       even have the security of positional parameters.
94
95       While every attempt will be made to interpret a flat list correctly, we
96       will make a transition to named parameters as elements of a hash
97       reference.  Devel::Comments users are encouraged to use this newer
98       calling syntax.
99
100       Following sections are headed by the appropriate hashref key, which
101       begins always with a leading dash. NOTE: This early version 1.1.2 does
102       not yet implement hashref calling syntax for parameters other than
103       "-filename".  Other sections are headed by the hashref keys that will
104       name their parameters. If the named parameter is unimplemented, you can
105       still pass the argument in the flat list.
106
107       -fh
108
109       named parameter syntax unimplemented
110
111       Example arguments: *STDOUT, "\*FH", $fh
112
113       Accepts an open, writable filehandle (typeglob or object) as an
114       argument.  Caller must do whatever is needed to manage that filehandle,
115       such as opening (but probably not closing) it.
116
117       Value must be acceptable as a filehandle:
118
119           $fh         # indirect filehandle (perhaps IO::File object); recommended.
120           \*FH        # reference to a typeglob
121           *FH         # typeglob
122           "FH"        # please don't do this; probably won't work as expected.
123
124       Except for *STDOUT you should probably avoid the typeglob notation.
125       (No need to specify *STDERR explicitly; it's the default.)  DC will try
126       to work with a typeglob but there are risks. You'd better localize the
127       typeglob; a lexical may not work. (See "Perl Cookbook Recipie 7.16".)
128       Passing a string will probably fail.
129
130       See also "perldoc perlopentut".
131
132       Note that, effectively, modules are used within a BEGIN block.
133       Therefore, your filehandle must be opened within a BEGIN block prior to
134       the use line. If caller needs to do anything else with that filehandle,
135       you might as well store it in a package variable (since source
136       filtering is global anyway).  Do not enclose the open and the use line
137       in the same BEGIN block.
138
139       The filehandle must be opened, obviously, in some writable mode.
140
141           BEGIN {                             # get $::fh open early enough
142               my $filename    = 'my.log';
143               open my $::fh, '>', $filename
144                   or die "Couldn't open $filename to write", $!;
145           }
146           use Devel::Comments $::fh;
147           {...}   # do some work
148           ### $some_variable
149           print {$::fh} 'Some message...';    # do something else with $::fh
150
151       -file
152
153       flat list parameter syntax unimplemented
154
155       Example arguments: '/var/my.log', "$0.log", 'ziggy.txt'
156
157       Value can be any filename or path, relative or fully qualified. The
158       file will be created if it doesn't exist, truncated by default, opened
159       for writing, and set to autoflush. All directory components must exist.
160
161       Until your entire program ends, there's no way to be sure that caller
162       won't come into scope (say, a sub called from some other script or
163       module). So DC can't do an explicit "close()". That shouldn't be a
164       problem, since perl will close the filehandle when program terminates.
165       If you need to do something differently, supply a filehandle and manage
166       it yourself.
167
168       You may, in an upcoming version, pass a filename as a flat list
169       argument.  There's an issue here in that a filename might be just about
170       any string; if you've chosen a peculiar filename such as '###' or
171       '-ENV', there's going to be confusion. For now, this is unimplemented.
172
173       -level
174
175       named parameter syntax unimplemented
176
177       numerical levels unimplemented
178
179       Devel::Comments accepts arguments like '###', '####', and so forth. If
180       none are given, then all comments introduced with 3 or more octothorpes
181       are considered smart. Otherwise, only those comments introduced with a
182       matching quantity are smart:
183
184           use Devel::Comments '###', '#####';
185           ### This is smart.
186           #### This is dumb.
187           ##### This is also smart.
188
189       Soon, you will be able to pass an integer or a list of integers:
190
191           use Devel::Comments ({-level => [3, 5] });
192           ### This is smart.
193           #### This is dumb.
194           ##### This is also smart.
195
196       But not quite yet.
197
198       A level of 1 or 2 simply doesn't work. So don't do that.
199
200       -env
201
202       named parameter syntax unimplemented
203
204       Example: "use Devel::Comments -ENV;"
205
206       Yet another way of specifying arguments (besides as a list or hashref
207       in the use line) is to pass them in the environment variable
208       $ENV{Devel_Comments}. But to enable this, you must pass "-ENV" in the
209       use line or define "-env" in a hashref passed in the use line.
210
211       See "CONFIGURATION AND ENVIRONMENT".
212
213       Don't try to pass a hashref inside of the environment variable; you
214       won't like the result.
215
216   Smart Comments Format
217       In some small way, smart comments comprise an alternate language
218       embedded within Perl. If you don't have any smart comments in your
219       code, Devel::Comments, like Smart::Comments before it, will do
220       essentially nothing. If you disable Devel::Comments (see "DISABLING"),
221       then smart comments are guaranteed to do nothing at all, since they are
222       then interpreted by perl as plain old dumb comments.
223
224       All smart comments, without exception, are introduced by a series of
225       three or more octothorpes: '###' at a minimum. This is not likely to
226       change; the '##' sequence is used by Perl::Tidy to signal the end of
227       lengthy constructs.
228
229       Aspects of this miniature language-within-a-language now include
230       introducers, messages, dumps, assertions, and progress bars. Extensions
231       are planned.
232
233       Introducers
234
235       A basic smart comment is any line beginning with '###':
236
237           ### This comment is smart at debug level 3.
238
239       This is considered a level 3 comment; it will only be active if level 3
240       is enabled by one means or another. More octothorpes increase the debug
241       level:
242
243           ##### This comment is smart at debug level 5.
244
245       The number of debugging levels is essentially unlimited; so introducers
246       may be of any length. However, this rapidly becomes unwieldy.
247
248       unimplemented: An alternate means of specifying the debug level is:
249
250           ###4 This comment is smart at debug level 4.
251
252       Every introducer ends with a space or tab ("m/[ \t]/"); anything before
253       the first white character is considered part of the introducer.
254
255       unimplemented: An introducer ending in an ampersand ("&") marks raw
256       Perl code; in effect, the introducer is simply stripped off if it is at
257       an enabled debug level:
258
259           ###& push @zoo, $monkey     # Put the monkey in the zoo at debug level 3.
260
261       Note that, with the exception of progress bars, a smart comment must
262       begin its line; that is, only whitespace can intervene between an
263       introducer and the preceeding newline. Trailing smart comments may be a
264       future feature.
265
266       Messages
267
268       Any smart comment not matching other patterns will be dumped as is:
269
270           ### Hello, World!
271
272       In a message, "<now>", "<time>", or "<when>" is replaced by a timestamp
273       (same timestamp for all three).  Also, "<here>", "<place>", or
274       "<where>" is replaced by what Damian Conway calls a "spacestamp"
275       similar to what you see by default in "die()" or "warn()":
276
277           ### Here <here>
278           ### Now <now>
279
280       prints something like:
281
282           ### Here "util/demo.pl", line 71
283           ### Now Fri Aug  6 07:50:51 2010
284
285       Note that no colon follows 'Here' or 'Now'. Any text would do as well
286       but no text at all -- the "<now>" alone -- gets confused. This is
287       considered a bug.
288
289           ### <here>      <now>
290
291       ... works fine and is an excellent way to start off a logging session.
292
293       Original SC documentation required that such plain text messages be
294       terminated with a simulated elipsis:
295
296           ### This text is printed...
297
298       This was not actually enforced and is not required in DC.
299
300       Dumps
301
302       Any scalar, array, hash; reference to any of these, or for that matter,
303       more complex structure can be dumped just by typing the variable:
304
305           ### $dump_me
306
307       The dump will be labeled with the variable name, including sigil.  You
308       can supply your own label if you like:
309
310           ### Working tree: $tree
311
312       The automatic labeling is the real driving force behind DC, though.
313       Even dark magiks involving Pad::Walker and rooting around in symbol
314       tables has trouble getting the right name for a variable and its value.
315       The only place it is convenient to do this is in the same scope as the
316       variable itself; hence, a source filter.
317
318       You can dump an arbitrary expression:
319
320           my $index   = 8;
321           ### Add five: $index + 5
322
323       prints:
324
325           ### Add five: 13
326
327       However, this will not work if you don't supply your own label.
328
329       Beware side effects:
330
331           my @array   = ( 1, 2, 3 );
332           say @array;
333           ### Pop: pop @array
334           say @array;
335
336       prints:
337
338           123
339
340           ### Pop: 3
341           12
342
343       If you don't want the verbosity of "<here>", try:
344
345           #### At: __LINE__
346
347       Assertions
348
349       Seven keywords cannot be used as labels. If one of them is used to
350       label an expression, it is evaluated in boolean context and, if the
351       expression is true, nothing is output. If the expression is false, a
352       message announcing the failure is output, similar to "warn()":
353
354           ### check:      1 == 0
355
356       prints something like:
357
358           ### 1 == 0 was not true at util/demo.pl line 92.
359
360       The assertions:
361
362           ### check:      BOOL
363           ### confirm:    BOOL
364           ### verify:     BOOL
365
366       ... simulate "warn()" on failure, although the smart output goes to the
367       chosen output file or filehandle, not necessarily STDERR.
368
369           ### assert:     BOOL
370           ### ensure:     BOOL
371           ### insist:     BOOL
372           ### require:    BOOL
373
374       ... print the same message on failure, then call "die()".
375
376       Note that these seven keywords are supported in the current version of
377       DC but all except "check" and "assert" are deprecated.
378
379       Progress Bars
380
381       Only in these can a smart comment appear on the same line with Perl
382       code:
383
384           for (@candidates) {       ### Evaluating |===[%]    |
385
386       prints, in succession:
387
388           Evaluating |[0%]                       |
389           Evaluating |=[25%]                     |
390           Evaluating |========[50%]              |
391           Evaluating |===============[75%]       |
392           Evaluating |===========================|
393
394       At each step, the previous bar is erased and overwritten by the next;
395       when the loop completes, the last bar is erased, too.
396
397       There are a great number of possible progress bar formats and they are
398       very clever indeed. There is, however, among developers polled, almost
399       no interest in them; and they are difficult to support. It's not clear
400       that they're truly useful in debugging. So, although they are supported
401       in the current DC release, they likely will be deprecated or replaced
402       by a different loop reporting function.
403
404       Both Vanilla and DC animate the progress bar by printing the "\r"
405       character and wiping the line with spaces. This is unchanged when smart
406       output goes to a disk file. Depending on your method of reading that
407       file, you may see multiple lines or nothing at all. But if, for some
408       reason, the loop aborts, you may see how far along it got.
409
410       If you want to experiment with progress bars, you may want to look at
411       the Smart::Comments documentation. If you like them, please be sure to
412       indicate your support.
413

DISABLING

415       Source filters are a bit dicey; the saving grace of DC (and its parent)
416       is that it can be disabled easily and completely; all specially-
417       formatted smart comments return to being plain old dumb comments,
418       guaranteed not to interfere with normal execution:
419
420           #use Devel::Comments;       # disable in production
421           ### assert 0 == 1           # does nothing at all
422
423       There are other methods of disabling DC.
424
425       If you write:
426
427           use Devel::Comments -ENV;   # heed environment variable
428
429       ... then DC will only be active if $ENV{Devel_Comments} is set,
430       possibly to some other DC use-line arguments or mererly to 1.  If it is
431       set to 0 or deleted, then DC is disabled.
432
433       DC can be restricted to a certain span of code. If you write:
434
435           ### Hello, Andy!
436           use Devel::Comments;
437           ### Hello, Bob!
438           no  Devel::Comments;
439           ### Hello, Cindy!
440
441       then Bob will be greeted but not Andy or Cindy. Note that docs for
442       Filter::Simple suggest other possible text for the statement that
443       terminates filtering; these others don't seem to work, so don't do
444       that.
445
446       You might load DC in the shell invocation:
447
448           $ perl -d:Comments myscript.pl
449
450       Next time, don't do that and DC won't load, of course. This loading
451       method is untested but if there are requests for it, I'll work it up.
452
453       Any given smart comment can be disabled by changing the introducer to a
454       level that's disabled in the use line, or to an invalid introducer:
455
456           use Devel::Comments '###';
457           ### grin
458           #### and
459           # ### bear
460           # ## it
461
462       prints:
463
464           ### grin
465

HOW IT WORKS

467       Technically, arguments present on any "use" line are presented to a
468       module's "import()" method. Devel::Comments uses Filter::Simple to do
469       the heavy lifting; FS converts a call to Filter::Simple::FILTER into
470       Devel::Comments::import().
471
472       All of the following code, to end of file or any "no Devel::Comments"
473       line, is filtered. All smart comments (with correct introducers) are
474       replaced by executable Perl code.
475
476       If you write something funky, like:
477
478           my $string = q{
479               bobby says
480               ### think
481           };
482
483       ... then you are asking for trouble and will likely get it.
484
485           my $string = q{\n    bobby says\n    ### think\n};
486
487       ... is perfectly safe and will be ignored by DC.
488
489       Dumps of complex structures are done by the venerable Data::Dumper.
490       The output is cleaned up a bit before being printed; the all-important
491       variable identifier is inserted.
492
493   Scope, State, Output Regimes
494       DC may be called more than once in the same program, e.g., from two
495       different loaded modules. As does vanilla SC, DC has effect until the
496       end of the file or a "no Devel::Comments" line (which must be the first
497       thing on its line). If used again, DC will parse the new use line and
498       apply it to your source code from there on out.
499
500       This required no special logic in Vanilla; the filter is applied once
501       per use and although multiple modules might call S::C routines from
502       within filtered code, all output went to STDERR. But multiple uses of
503       DC may choose different output regimes. So state information is stored
504       for each caller.
505
506       If you supply a filehandle (other than STDOUT or STDERR), your
507       (filtered) code will need that later to print smart output where you
508       want it to go. If you supply a package variable as an indirect
509       filehandle (such as $My::Module::fh), then all is well. If you supply a
510       lexical ("my") variable, DC will still work, even after it goes out of
511       scope in your package, because a reference is stored in DC's namespace.
512       But by the same token, don't expect it to be garbage-collected. You may
513       as well use a package "global" variable, since source filtering is
514       pretty much a global operation anyway.
515
516       If you pass a filename but no filehandle, you'll get smart output but
517       you won't have any way to write directly to the file (should you take
518       that notion). Not recommended to open the file again within your
519       script, although that might work.
520

DIAGNOSTICS

522           Internal error: _get_outfh called with no or false arg. $!
523           Internal error: $caller_id not defined in %state_of. $!
524           Internal error: No output filehandle found in %state_of for $caller_id. $!
525           Internal error: -caller_id not passed in call to _init_state(). $!
526           Internal error: -outfh not passed in call to _init_state(). $!
527
528       You should never see any of these errors involving state maintenance.
529       If you do, please contact the author with as much information as
530       possible.
531
532           Can't open $out_filename to write.
533
534       You passed in a filename that couldn't be written to. Check to see that
535       all directory components of the path exist and that you have permission
536       to write to the target file.
537
538           Filesystem IO error: Failed to print to output filehandle for $caller_id
539
540       Gee, that's funny. But if DC can't write to a filehandle you supplied,
541       it's probably not something I can do anything about.  Perhaps the disk
542       is full or the socket is closed?  Be sure you have opened the
543       filehandle for writing in a BEGIN block prior to the "use
544       Devel::Comments;" line. Check to see you can write to it.
545
546           Internal error: DATA. $!
547
548       You should never see this error either.  If you do, please contact the
549       author with as much information as possible.
550
551           ### $assertion was not true
552
553       This is not a module error but smart output you generated. See
554       "ASSERTIONS"
555

CONFIGURATION AND ENVIRONMENT

557       Devel::Comments can make use of an environment variable from your
558       shell: "Devel_Comments". This variable can be specified either with a
559       true/false value (i.e. 1 or 0) or with the same arguments as may be
560       passed on the "use" line when loading the module (see "INTERFACE").
561       The following table summarizes the behaviour:
562
563                Value of
564           $ENV{Devel_Comments}          Equivalent Perl
565
566                   1                     use Devel::Comments;
567                   0                      no Devel::Comments;
568               '###:####'                use Devel::Comments qw(### ####);
569               '### ####'                use Devel::Comments qw(### ####);
570
571       To enable the "Devel_Comments" environment variable, you need to load
572       the module with the "-ENV" flag:
573
574           use Devel::Comments -ENV;
575
576       Note that you can still specify other arguments in the "use" statement:
577
578           use Devel::Comments -ENV, qw(### #####);
579
580       In this case, the contents of the environment variable replace the
581       "-ENV" in the argument list.
582

DEPENDENCIES

584       The module requires the following modules:
585
586       ·   Filter::Simple
587
588       ·   version.pm
589
590       ·   List::Util
591
592       ·   Data::Dumper
593
594       ·   Text::Balanced
595

INCOMPATIBILITIES

597       It is known that IO::Capture::Tie_STDx 0.05 does not implement a
598       "TELL()" method. This causes trouble if smart output is directed to a
599       captured filehandle. Workaround is to install IO::Capture::Tellfix,
600       included with this distribution.
601
602       Not recommended to use DC is combination with other source filters.
603

BUGS AND LIMITATIONS

605       Tellfix is ugly and causes a warning to be raised under some
606       circumstances.  Intent is to move off IO::Capture::* altogether in
607       favor of Test::Trap; so this issue will not be fixed directly.
608
609       The current testing paradigm is flawed; it has too many dependencies,
610       including perl 5.010. We ship with a cut-down "user" test suite, which
611       should run fine under perl 5.008; this is mostly a rehash of the
612       original Smart::Comments test suite and doesn't fully exercise DC's new
613       features.  Those interested may want to run the full test suite found
614       in t/all/.
615
616       A number of features are marked as unimplemented.
617
618       Bugs outstanding against SC 1.0.4 can be found at
619       <https://rt.cpan.org/Dist/Display.html?Queue=Smart-Comments> and they
620       are probably all present in this version of DC. You are welcome to
621       relist against DC any that you find; but I will be working off that
622       list, too.
623
624       Please report any bugs or feature requests to
625       <https://rt.cpan.org/Public/Bug/Report.html?Queue=Devel-Comments> or
626       email "<XIONG@cpan.org>". These are welcome and will be acted upon.
627

TODO

629       Argment passing will be made orthogonal, as much as possible. Arguments
630       can be passed either as one flat list or as named elements of a single
631       hashref.
632
633       Debug levels passed numerically and numerical introducers.
634
635       Invocation of client methods for dumping objects.
636
637       Pass-through execution of arbitrary debugging code.
638
639       Police up scraps of stuff currently left in caller's namespace. Store
640       all state entirely within DC.
641

THANKS

643       ·   Mike Stok "<MIKESTOK@cpan.org>" for reporting RT#62599 and fixing
644           it.
645
646       ·   Kevin Ryde for reporting RT#69712 and reviving the project.
647

AUTHOR

649       Xiong Changnian  "<XIONG@cpan.org>"
650
652       Copyright (c) 2010, 2011, Xiong Changnian  "<XIONG@cpan.org>". All
653       rights reserved.
654
655       Based almost entirely on Smart::Comments, Copyright (c) 2005, Damian
656       Conway "<DCONWAY@cpan.org>". All rights reserved.
657
658       This module is free software; you can redistribute it and/or modify it
659       under the same terms as Perl itself.
660

DISCLAIMER OF WARRANTY

662       BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
663       FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT
664       WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
665       PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND,
666       EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
667       WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
668       ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
669       YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
670       NECESSARY SERVICING, REPAIR, OR CORRECTION.
671
672       IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
673       WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
674       REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE
675       TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR
676       CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
677       SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
678       RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
679       FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
680       SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
681       DAMAGES.
682
683
684
685perl v5.30.1                      2020-01-29                Devel::Comments(3)
Impressum