QuinsUK
QuinsUK

Reputation: 371

$ARGV [1] Perl problems

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

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

Answers (4)

Edward L
Edward L

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

Lucas
Lucas

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

zostay
zostay

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

scrappedcola
scrappedcola

Reputation: 10572

You should do string comparisons with eq not ==.

if ($ARGV[1] eq "debug")

Upvotes: 3

Related Questions