Reputation: 371
I am currently trying to set a debug flag using command-line arguments in Perl and I seem to be having problems with something which I thought was pretty easy.
my $debugvalue;
my $file = $ARGV[0] or die;
if ($ARGV[1] == "debug")
{
$debugvalue = 1;
}else
{
$debugvalue = 0;
}
I am looking to enter a file followed by a word purely saying debug, if it doesn't then set the flag to 0.
test.pl file.txt debug
Would set the flag to 1
test.pl file.txt debug
Would set the flag to 0
I would assume this how you do this, except whatever is inputted, it always drops into the first part of the if and sets the flag to 1.
Upvotes: 1
Views: 2542
Reputation: 56
As folks have already pointed out that "eq" should be used for string comparisons and other ways of supporting a debug feature, the only other suggestions I'd add is that using perl's -w (warning) flag during development is also helpful for finding issues like yours:
#!/usr/bin/perl -w
In your initial example, it would've returned a warning like:
Argument "debug" isn't numeric in numeric eq (==) at ./foo.pl line 7.
It might also be cleaner to check for the existence of $ARGV[1] before using it in a comparison:
if ($ARGV[1] && $ARGV[1] eq "debug")
{
$debugvalue = 1;
...
Upvotes: 1
Reputation: 14949
I almost always use Getopt or Getopt::Long. Both in CPAN, super simple to use and very standardized. For example:
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
my $debug = 0;
my $result = GetOptions(
debug => \$debug
);
my $file = shift;
if ( $debug ) {
print( "debug is on for processing $file..." );
}
Of course, because it uses standard syntax, you would call it thusly:
#> test.pl file.txt --debug
or
#> test.pl --debug file.txt
---- EDIT ----
@zostay brings up a good point, debugging at various levels can be very useful. That can be added in to the Getopot::Long approach thusly:
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
my $debug = 0;
my $result = GetOptions(
"debug+" => \$debug
);
my $file = shift;
if ( $debug > 2 ) {
print( "debug is at least level 2 for processing $file..." );
}
And, for level 2 debugging, would be called:
#> test.pl --debug --debug file.txt
Upvotes: 4
Reputation: 3995
That would work fine, but you need to use the string comparison, eq
, rather than numeric comparison, ==
.
if ($ARGV[1] eq "debug")
Also, you can shorten that up to just:
my $debugvalue = $ARGV[1] eq "debug";
In general, I prefer to use the environment for debug settings, though.
my $debugvalue = $ENV{DEBUG} || 0;
Then you can do things like:
DEBUG=1 test.pl file.txt
or set the test on for every run in bash or zsh:
export DEBUG=1
test.pl file.txt
test.pl file2.txt
test.pl file3.txt
or even have more than one debug level if you need aggressive debugging output to help diagnose a particular problem:
DEBUG=3 test.pl file.txt
and in your code:
warn "Fiddly Detail $x\n" if $debugvalue > 2;
Upvotes: 5
Reputation: 10572
You should do string comparisons with eq
not ==
.
if ($ARGV[1] eq "debug")
Upvotes: 3