note
Rudif
Thank you [ikegami], [Joost] and [Sidhekin] <p>
<i>The *option's argument* is required, not the option itself.
</i><p>
<i>What is "mandatory" and "optional" is not the option itself (options are by their nature always optional) but rather the associated argument.</i><p>
<i>In other words, the additional processing is only invoked if the arguments are specified.</i><p>
Right, you clarified what was confusing me.<p>
<i>I would prefer the is_deeply method of comparing complex structure.</i> <p>
I agree, now that you mentioned it: easier to read, easier to update when developing the script.<p>
I also found an interesting discussion of its limitations and alternatives in [id://476435]<p>
The revised script below reflects the insights. <p>
[Rudif]
<readmore>
<code>
#!perl -w
use strict;
my $version = 0.02;
use Getopt::Long;
$|++;
use Test::More tests => 32;
## The option name as specified to the GetOptions() function is called the option specification.
## Later we'll see that this specification can contain more than just the option name.
## The reference to the variable is called the option destination.
{
my $case = "Case 1 - from module synopsis";
local @ARGV = ();
my $data = "file.dat";
my $length = 24;
my $verbose;
my $result = GetOptions(
"length=i" => \$length, # numeric
"file=s" => \$data, # string
"verbose" => \$verbose # flag
);
ok( $result, 'Case 1 from module synopsis' );
is_deeply( [ $data, $length, $verbose ], [ 'file.dat', 24, undef ], 'Case 1 from module synopsis' );
}
## For options that take values it must be specified whether the option value is required or not, and what kind of value the option expects.
## Three kinds of values are supported: integer numbers, floating point numbers, and strings.
## If the option value is required, Getopt::Long will take the command line argument that follows the option and assign this to the option variable.
## If, however, the option value is specified as optional, this will only be done if that value does not look like a valid command line option itself.
{
my $case = "Case 2 - option has default value, none given";
local @ARGV = ();
my $tag = 'deftag';
my $result = GetOptions( 'tag=s' => \$tag );
ok( $result, $case );
is_deeply( [$tag], ['deftag'], $case );
}
{
my $case = "Case 3 - option has default value, option with value given";
local @ARGV = ('--tag=MYTAG');
my $tag = 'deftag';
my $result = GetOptions( 'tag=s' => \$tag );
ok( $result, $case );
is_deeply( [$tag], ['MYTAG'], $case );
}
{
my $case = "Case 4 - option has default value, option with value and unknown option given";
local @ARGV = ('--bingo --tag=OTHERTAG');
my $tag = 'deftag';
my $result = GetOptions( 'tag=s' => \$tag );
ok( !$result, $case );
is_deeply( [$tag], ['deftag'], $case );
}
## In the option specification, the option name is followed by an equals sign = and the letter s.
## The equals sign indicates that this option requires a value.
## The letter s indicates that this value is an arbitrary string.
## Other possible value types are i for integer values, and f for floating point values.
{
my $case = "Case 5a - options have no default values, option values required if option given, no options given";
local @ARGV = ();
my $tag;
my $ival;
my $result = GetOptions(
'tag=s' => \$tag,
'ival=i' => \$ival
);
ok( $result, $case );
is_deeply( [ $tag, $ival ], [ undef, undef ], $case );
}
{
my $case = "Case 5b - options have no default values, option values required if option given, options with values given";
local @ARGV = ( '--tag=thisyear', '--ival=2007' );
my $tag;
my $ival;
my $result = GetOptions(
'tag=s' => \$tag,
'ival=i' => \$ival
);
ok( $result, $case );
is_deeply( [ $tag, $ival ], [ 'thisyear', 2007 ], $case );
}
{
my $case = "Case 5c - options have no default values, option values required if option given, options without values given";
local @ARGV = ( '--tag', '--ival' );
my $tag;
my $ival;
my $result = GetOptions(
'tag=s' => \$tag,
'ival=i' => \$ival
);
ok( $result, $case );
is_deeply( [ $tag, $ival ], [ '--ival', undef ], $case );
}
{
my $case = "Case 5x - options have default values, option values required if option given, no options given";
local @ARGV = ();
my $tag = 'deftag';
my $ival = -1;
my $result = GetOptions(
'tag=s' => \$tag,
'ival=i' => \$ival
);
ok( $result, $case );
is_deeply( [ $tag, $ival ], [ 'deftag', -1 ], $case );
}
{
my $case = "Case 5y - options have default values, option values required if option given, options with values given";
local @ARGV = ( '--tag=thisyear', '--ival=2007' );
my $tag = 'deftag';
my $ival = -1;
my $result = GetOptions(
'tag=s' => \$tag,
'ival=i' => \$ival
);
ok( $result, $case );
is_deeply( [ $tag, $ival ], [ 'thisyear', 2007 ], $case );
}
{
my $case = "Case 5z - options have default values, option values required if option given, options without values given";
local @ARGV = ( '--tag', '--ival' );
my $tag = 'deftag';
my $ival = -1;
my $result = GetOptions(
'tag=s' => \$tag,
'ival=i' => \$ival
);
ok( $result, $case );
is_deeply( [ $tag, $ival ], [ '--ival', -1 ], $case );
}
## Using a colon : instead of the equals sign indicates that the option value is optional.
## In this case, if no suitable value is supplied, string valued options get an empty string '' assigned, while numeric options are set to 0.
{
my $case = "Case 6a - options have no default values, option values not required if options given, no options given";
local @ARGV = ();
my $tag;
my $ival;
my $result = GetOptions(
'tag:s' => \$tag,
'ival:i' => \$ival
);
ok( $result, $case );
is_deeply( [ $tag, $ival ], [ undef, undef ], $case );
}
{
my $case = "Case 6b - options have no default values, option value not required if option given, options with values given";
local @ARGV = ( '--tag=thisyear', '--ival=2007' );
my $tag;
my $ival;
my $result = GetOptions(
'tag:s' => \$tag,
'ival:i' => \$ival
);
ok( $result, $case );
is_deeply( [ $tag, $ival ], [ 'thisyear', 2007 ], $case );
}
{
my $case = "Case 6c - options have no default values, option value not required if option given, options without values given";
local @ARGV = ( '--tag', '--ival' );
my $tag;
my $ival;
my $result = GetOptions(
'tag:s' => \$tag,
'ival:i' => \$ival
);
ok( $result, $case );
is_deeply( [ $tag, $ival ], [ '', 0 ], $case );
}
{
my $case = "Case 6x - options have default values, option values not required if options given, no options given";
local @ARGV = ();
my $tag = 'deftag';
my $ival = -1;
my $result = GetOptions(
'tag:s' => \$tag,
'ival:i' => \$ival
);
ok( $result, $case );
is_deeply( [ $tag, $ival ], [ 'deftag', -1 ], $case );
}
{
my $case = "Case 6y - options have default values, option value not required if option given, options with values given";
local @ARGV = ( '--tag=thisyear', '--ival=2007' );
my $tag = 'deftag';
my $ival = -1;
my $result = GetOptions(
'tag:s' => \$tag,
'ival:i' => \$ival
);
ok( $result, $case );
is_deeply( [ $tag, $ival ], [ 'thisyear', 2007 ], $case );
}
{
my $case = "Case 6z - options have default values, option value not required if option given, options without values given";
local @ARGV = ( '--tag', '--ival' );
my $tag = 'deftag';
my $ival = -1;
my $result = GetOptions(
'tag:s' => \$tag,
'ival:i' => \$ival
);
ok( $result, $case );
is_deeply( [ $tag, $ival ], [ '', 0 ], $case );
}
__END__
</code>
</readmore>
640616
640616