1

Is there any way to check my input (value) is provided or not when using GetOptions?

#file testing.pl
#!/usr/5.14.1/bin/perl
use strict;


use Getopt::Long qw(:config no_ignore_case no_auto_abbrev);
Getopt::Long::Configure("no_pass_through");

#default value
my $testing = 0;
my $loc = undef;

my %opt_map {
  "-test" => $testing,
  "-location=s" => $loc,
}

GetOptions(%opt_map) or die("Parameter is not exist");

then I call the file with:

testing.pl -test -location /a/bc/def

Is there anyway to check /a/bc/def is provided or not? The option is optional but the value is mandatory.

If /a/bc/def is not provided then the $location value is became 1 instead of undef.

AND if -location argument is on the front, it will consume the next option as its value. example:

testing.pl -location -test
#the result is 
$loc = "-test"
Archmal
  • 63
  • 1
  • 8
  • I only pull out snippet of the code. the actual code is longer. this one is just the problem parts – Archmal Dec 01 '20 at 00:50
  • 1
    Always make minimal, complete working examples. Part of figuring out how small things work is to make separate pieces work in small exploratory programs. – brian d foy Dec 01 '20 at 01:25
  • `or die( "Parameter is not exist" );` makes no sense. It should be `or exit(1);` – ikegami Dec 01 '20 at 06:13
  • 1
    I've been using Getopt::Kingpin lately, and it can automatically enforce required parameters for you, as well as having a whole bunch of useful features Getopt::Long lacks, and a nicer API. – tobyink Dec 01 '20 at 13:17

2 Answers2

2

First, if you start your variables with undef, then you can tell if they were on the command line by checking after you process the command line arguments. An optional value ends up as the empty string if the option was specified without a value. You can make an option take an optional value with : instead of = (which makes it a mandatory value):

use v5.12;
use Getopt::Long;

my $loc;

my %opts = (
    "location:s" => \$loc,
    );

GetOptions( %opts ) or die( "Parameter is not exist" );

say "Location is defined" if defined $loc;
say "Location is $loc";

A few runs:

$ perl test.pl --location /a/b/c
Location is defined
Location is /a/b/c

$ perl test.pl --location
Location is defined
Location is

$ perl test.pl
Location is

I couldn't discern if you wanted to set a default value of 1. You can use a code reference to modify the value if it's the empty string:

use v5.12;
use Getopt::Long;

#file testing.pl
my $abc;
my $loc;

my %opts = (
    "location:s" => sub { $loc = $_[1] ne '' ? $_[1] : 1 },
    );

GetOptions( %opts ) or die( "Parameter is not exist" );

say "Location is $loc";

Some runs:

$ perl test.pl --location
Location is 1

$ perl test.pl --location /a/b/c
Location is /a/b/c

$ perl test.pl
Location is

UPDATE

Here's the program which adds in another option. This isn't a problem.

use v5.12;
use Getopt::Long;

my $test;
my $loc;

my %opts = (
    "location:s" => sub { $loc = $_[1] ne '' ? $_[1] : 1 },
    "test"       => \$test,
    );

GetOptions( %opts ) or die( "Parameter is not exist" );

say "Location is $loc";
say "Test is $test";

And some runs, where I can't reproduce your claim:

$ perl test.pl --location /a/b/c --test
Location is /a/b/c
Test is 1

$ perl test.pl --location --test
Location is 1
Test is 1
brian d foy
  • 129,424
  • 31
  • 207
  • 592
  • my big problem is the option that i provide consuming other option as arguments. means if i put -location -test, the location argument is "-test". the option is optional but the arguments is mandatory if the option is provide – Archmal Dec 01 '20 at 01:55
  • Did you try that with my code? I can't reproduce that problem. – brian d foy Dec 01 '20 at 03:06
0

You can find the documentation for Getopt::Long here or by typing perldoc Getopt::Long in your terminal.

# You start your code with 
use strict;
use warnings;
use v5.032;
# GetOptions() is imported from Getopt::Long, so you have to use it
use Getopt::Long;

my($test,$loc);

# you want GetOptions to modify the variables, therefore you need to pass
# a reference instead of the value
my %opt_map= (
  "-test" => \$test, 
  "-location=s" => \$loc,
);

# GetOptions will warn for missing params, if your opts definition requires so
GetOptions(%opt_map) or die("Parameter is not exist");

# check the variables content
say $loc ? "location is [$loc]" : "no location passed";
say $test ? "test is [$test]" : "no test passed";

__END__

perl test.pl  -location /a/bc/def
location is [/a/bc/def]
no test passed


perl test.pl   -location 
Option location requires an argument
Parameter is not exist at test.pl line 13.

Update:

If you specify "-location=s" => \$loc (mandatory) and "-test" => \$test, (optional), then after calling with test.pl --location --test GetOptions places '--test' in $loc leaving $test undefined. (Perhaps to satisfy both conditions?)

One solution to this is to make "-location:s" => \$loc optional (see the other answer), then check the variables after GetOptions() was called. In your case $loc would be allowed to be undef (not specified) or a non-empty string.

use strict;
use warnings;
use v5.032;
use Getopt::Long;
my($test,$loc) ;
my %opt_map= (
              "test" => \$test,
              "location:s" => \$loc,
);

GetOptions(%opt_map);# or die("Parameter is not exist");

for ($loc,$test){$_ = defined $_? $_ : 'undefined'}

if ($loc eq ''){warn "found location without value\n";exit 1}

say "location is [$loc]" ;
say  "test is [$test]";

trying it:

perl test.pl   
location is [undefined]
test is [undefined]

perl test.pl   --location
found location without value

perl test.pl   --location --test
found location without value

perl test.pl   --location /a/bc/def --test
location is [/a/bc/def]
test is [1]
clamp
  • 2,552
  • 1
  • 6
  • 16
  • I need to check either the location is provided. means $loc is "/a/bc/def" instead of 1. my problem now is the $loc value is 1 because I didnt provide any value. eventhough i already specified "-location=s" not just "-location" – Archmal Dec 01 '20 at 00:55
  • Please run the example I provided - perhaps comment the `die` - and see how it behaves. There is no way `$loc` can end up with a value of 1 except you passing it (1) explicitly as cmdline argument. – clamp Dec 01 '20 at 01:01
  • @Archmal : I see your issue now and updated the answer. – clamp Dec 01 '20 at 08:52