I am learning Perl in a “head-first” manner. I am absolutely a newbie in this language:
I am trying to have a debug_mode switch from CLI which can be used to control how my script works, by switching certain subroutines “on and off”.
And below is what I’ve got so far:
#!/usr/bin/perl -s -w
# purpose : make subroutine execution optional,
# which is depending on a CLI switch flag
use strict;
use warnings;
use constant DEBUG_VERBOSE => "v";
use constant DEBUG_SUPPRESS_ERROR_MSGS => "s";
use constant DEBUG_IGNORE_VALIDATION => "i";
use constant DEBUG_SETPPING_COMPUTATION => "c";
our ($debug_mode);
mainMethod();
sub mainMethod # ()
{
if(!$debug_mode)
{
print "debug_mode is OFF\n";
}
elsif($debug_mode)
{
print "debug_mode is ON\n";
}
else
{
print "OMG!\n";
exit -1;
}
checkArgv();
printErrorMsg("Error_Code_123", "Parsing Error at...");
verbose();
}
sub checkArgv #()
{
print ("Number of ARGV : ".(1 + $#ARGV)."\n");
}
sub printErrorMsg # ($error_code, $error_msg, ..)
{
if(defined($debug_mode) && !($debug_mode =~ DEBUG_SUPPRESS_ERROR_MSGS))
{
print "You can only see me if -debug_mode is NOT set".
" to DEBUG_SUPPRESS_ERROR_MSGS\n";
die("terminated prematurely...\n") and exit -1;
}
}
sub verbose # ()
{
if(defined($debug_mode) && ($debug_mode =~ DEBUG_VERBOSE))
{
print "Blah blah blah...\n";
}
}
So far as I can tell, at least it works…:
- the -debug_mode switch doesn’t interfere with normal ARGV
- the following commandlines work:
- ./optional.pl
- ./optional.pl -debug_mode
- ./optional.pl -debug_mode=v
- ./optional.pl -debug_mode=s
However, I am puzzled when multiple debug_modes are “mixed”, such as:
- ./optional.pl -debug_mode=sv
- ./optional.pl -debug_mode=vs
I don’t understand why the above lines of code “magically works”.
I see both of the “DEBUG_VERBOS” and “DEBUG_SUPPRESS_ERROR_MSGS” apply to the script, which is fine in this case.
However, if there are some “conflicting” debug modes, I am not sure how to set the “precedence of debug_modes”?
Also, I am not certain if my approach is good enough to Perlists and I hope I am getting my feet in the right direction.
One biggest problem is that I now put if statements inside
most of my subroutines for controlling their behavior under different modes. Is this okay?
Is there a more elegant way?
I know there must be a debug module from CPAN or elsewhere, but I want a real minimal solution that doesn’t depend on any other module than the “default”.
And I cannot have any control on the environment where this script will be executed…
For handling command line options, take a look at Getopt::Long. You get all kinds of slick argument parsing options.
There are many, many modules that handle logging. Log4Perl is a very popular logging module.
If you really, really want to limit yourself by avoiding CPAN (which is a bad idea) you can pretty easily hack together a logging module.
Here’s a small one I hacked up for you. It needs tests and real docs and so forth. I also used some advanced techniques, like a custom
import()method. There are also some gotchas surrounding my use of a single variable to store the DEBUG settings for the whole app. But it works. I used a similar module on a project and was pretty happy with it.And then use it like this:
You might want to add a method to make your debug messages suppressable.
Something like:
Export the symbol and then use it like:
The ease with which a logging module can be thrown together has lead to there being a large number of such modules available. There are so many ways to accomplish this task and different variations on the requirements when instrumenting code that there are even more. I’ve even written a few logging modules to meet various needs.
Anyhow, this should give you a serious dunk in the water as you dive head-first into Perl.
Feel free to ask me ‘what the heck?’ type questions. I realize I’m throwing a lot at you.