NAME
Unpound - Simple "uncomment" debugging.
SYNOPSIS
# Some code executing...
#trace# print "Entered subroutine.\n";
$foo=&bar();
#debug# print "\$foo: $foo\n";
$rv=$foo/17; #debug# print "Inline comment: \$rv is $rv\n";
#debug#trace# print "About to return $rv\n";
DESCRIPTION
An even more simplified source filter, based on Filter::Simple and somewhat like Filter::Uncomment, but with a different syntax that might be easier to work with.
Anything commented out by a comment in the form #word#
can be uncommented by including this package with suitable arguments. Essentially, if you execute
perl -MFilter::Unpound=word script.pl
then the string "#word#" is removed wherever it may appear in the code-- which may then expose some previously commented-out instructions. You can have several different "uncomment" tags and use them selectively. A line tagged with more than one, as above, is activated if any one is activated. You can make it have to have all the tags this way:
#foo#bar# print "This line prints with either foo or bar.\n";
#foo# #bar# print "This line prints only with both.\n";
You would have to say perl -MFilter::Unpound=foo,bar
to get the second line to print, whereas either perl -MFilter::Unpound=foo
or perl -MFilter::Unpound=bar
will suffice for the first.
You can also uncomment multi-line pieces of code which are ordinarily commented out by wrapping them in a special "string comment" using Perl here-strings.
;<<'foo'
print "This code is normally ignored, just shoved into a string.\n";
foo
;
;my $__UNPOUND=<<'bar'
print "Also ignored code.\n";
print "The special UNPOUND dummy variable is for avoiding warnings\n";
bar
;
;$__UNPOUND=<<'lastly'
print "Same as above... ";
print "(except didn't declare $UNPOUND again.)\n";
lastly
;
The string comment header must appear just as shown: on its own line, with the keyword surrounded by single quotes, and the << must be preceded by a semicolon (just in case you have some code that uses a here-string that starts on its own line; the semicolon makes the string unusable for anything, so it can't be purposeful in your code.) Note that this will cause "void" warnings (during ordinary, not Unpounded, execution) if you have those enabled. You can optionally assign to a variable called $__UNPOUND
(you have to use that name) if you want to avoid the warnings. You can also optionally declare $__UNPOUND
with "my
" on the line as shown above. When "foo" is selected, Unpound will delete lines that look like ";<<'foo'
" and lines that have only "foo
" on them, so this code will be uncommented.
One or the Other
You can even use this to set up code to be commented, so you can have code that acts one way when debugging is off and does something else (not just more things) when debugging is on. Consider:
#debug# print "Doing debugging things.\n";
#debug# ;<<'XxXxXx';
print "Doing normal things, which will NOT be done when debugging.\n";
#debug# XxXxXx
#debug# ;
The "normal" code is eaten into the dummy string when debug is selected. Make sure there is no whitespace after your string terminator (Unpound will eat the whitespace before it)
Print Shorthand
Since most of the time debugging statements are print statements, you can save the hassle of typing "print" (or even "say") all the time by ending your single-line tag with '>'. The rest of the line (after whitespace) will be taken as a double-quoted string to be printed, followed by a newline. The line is quoted as a here-string, so there shouldn't be any problems with accidental end-quoting.
This feature is not available for multi-line uncomments.
LIMITATIONS
- -
-
The tags used must be simple ASCII words, consisting only of letters, numbers, and underscores.
- -
-
Although you can use your keywords inside quotes in ordinary code without their being affected by deletion, they will be affected in quotes inside code that becomes uncommented. That is:
print "This line will print #foo# and #bar# properly no matter what.\n"; #foo# print "But when uncommented, this (#foo#) will be empty.\n"; #foo# print "If foo and bar are both selected, (#bar#) is empty too.\n"; #foo# print "But this only affects the words when surrounded by #s.\n";
Basically, giving X as a parameter will cause
#X#
to disappear everywhere in the code, but not in strings. However, strings that were commented out before the filtering count as code too.This can produce some some unfortunate issues. Consider:
#keyword# print "This is a string with #keyword> in it.";
Since the auto-print feature does more than just delete its keyword, also eating the rest of the line, this will expand to:
print "This is a string with a print<<fFilLTereD in it."; fFilLTereD ;
Which naturally is not going to sit well with the rest of the parser. Moral of the story: avoid keywords that might occur inside strings with #-signs in front of/around them.
- NOTE
-
The above applies to Perl versions 5.10 and above. Due to a bug in Filter::Simple in lower versions of Perl, filtering only the code can produce bizarre and unexpected bugs in the presence of things like here-strings or formats, so Unpound will filter code, strings, and all on those versions (Ref. http://www.perlmonks.org/?node_id=513511). That means that the above-referenced problem with
#keyword>
can happen even in non-unpounded strings on lower versions of perl.
- -
-
To use Unpound inside a module which is going to be included via
use
from somewhere else, you have to get sneaky. Orinarily, the filters that apply to the base program don't reach into included libraries, which makes sense, since those libraries might have been written by anyone. But sometimes you want to debug a library in situ, where it's being used by another program already. For that, you have to do some work at the top of the module to explicitly "inherit" Unpound. Even though this is flagged with BEGIN, it won't apply to stuff before it in your file, presumably because all import stuff is in BEGIN anyway. So put this at the top of your file.# For use with Unpound for debugging BEGIN { no strict; if (exists($INC{'Filter/Unpound.pm'})) { my @z=Filter::Unpound::keywords; # watch for bareword interpretation... if (@z && $z[0] ne 'Filter::Unpound::keywords') { # Import throws away the first argument. Filter::Unpound::import("Dummy", @z); } } }
Unfortunately, this code doesn't disappear into harmless comments when there's no Unpound in use (though it does disappear into harmless code).
- -
-
Tricks like multi-line comments have to be used between statements, not within them, so you can't do stuff like uncommenting part of a list with them.
DIAGNOSTICS
None intended to come from Unpound itself.
AUTHOR
Mark E. Shoulson <mark@shoulson.com>
COPYRIGHT
Copyright (c) 2012, Mark Shoulson. All Rights Reserved. This module is free software. It may be used, redistributed, and/or modified under the terms of the Perl Artistic License (see http://www.perl.com/perl/misc/Artistic.html)