First, I should qualify all the following with the comment that I use Getopt::Long in all my own work; I've found it sufficiently powerful for all my needs, straight forward to use, and it's CORE so I don't have to worry about library management.
You've got a number of code problems, most of which which would be caught by strict. The strict pragma implements a number of restrictions on your code, such as requiring all variables be either declared with a my or our or have a fully qualified package name. See Use strict warnings and diagnostics or die.
So bugs in the provided code are:
-
On line 3, you call the class method new_parser, but have not wrapped the hash ref you are using as your parameter set in the necessary parentheses, nor have you terminated the line in a semi-colon. This syntax error causes compilation to fail, which tells me you did not try running your code example before posting. See How do I post a question effectively?. The correct call would be:
$ap = Getopt::ArgParse->new_parser(
{
prog => "test_argparse.pl",
description => "Test the Getopt::Argparse module"
}
);
or something close.
-
On lines 9 and 11, you failed to wrap the Scalar and Bool values in quotes, so (since you didn't have strict on) Perl attempted to run subs called Scalar and Bool, got undef and so passed that to the argument constructor. Those lines should be
$ap->add_argument('-c', '--count', type => 'Scalar');
$ap->add_argument('-f', '--flag', type => 'Bool');
=> stringifies the preceding argument, but you must still wrap the trailing argument in quotes. Other than that, it's just a comma.
-
The add_argument method uses the first passed flag name as the name for the field internally. Since you seem to want the field to be named count, not c, that should be
$ap->add_argument('--count', '-c', type => 'Scalar');
$ap->add_argument('--flag', '-f', type => 'Bool');
-
$ap->parse_args() returns a blessed hash reference, which is Perl's version of an object (<--simplification). However, on line 18, you attempt to access a hash named %args. Again, this is something strict would have caught. The correct way to dig about in a hash ref is to use the The Arrow Operator. In that case, line 18 should have read
if (! defined($args->{'count'})) {
HOWEVER, since $args is not just an ordinary hash ref, but an object, it is good practice to use the provided accessors. This protects you from typos in hash keys. The module provides two methods for accessing field names: either via the $args->get_attr(ARG) method, or via the Moose-like getter $args->ARG
So you could get your desire result with either
if (! defined($args->get_attr('count'))) {
or
if (! defined($args->count)) {
assuming you've made the argument order correction above.
So, a corrected version of your code that runs as expected is:
#!/usr/bin/perl -w
use strict;
require Getopt::ArgParse;
my $ap = Getopt::ArgParse->new_parser(
{
prog => "test_argparse.pl",
description => "Test the Getopt::Argparse module"
});
$ap->add_argument('--count', '-c', type => 'Scalar');
$ap->add_argument('--flag', '-f', type => 'Bool');
my $args = $ap->parse_args();
# Now, I am assuming that $args is a pointer to a hash array
# that contains elements for "count" and "flag"
if (! defined($args->count)) {
print "count not defined\n";
}
#11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.
| [reply] [d/l] [select] |
Kennethk,
Thanks for the corrections. Yes, the code, as posted on this page, won't compile/run. But the code isn't the exact code I have in my program. For reasons of "IT security", I could not "cut and paste" the code from my xterm window to the website. I entered the code by hand and I introduced a few syntax errors.
I will change my code based on feedback from Points 2-4 and try again. Thanks.
| [reply] |
I've never used this module either, but the documentation on CPAN has this to say:
parse_args
This object method accepts a list of arguments or @ARGV if unspecified, parses them for values, and stores the values in the namespace object.
[...]
The Namespace Object
The parsed values are stored in a namespace object. Any class with the following three methods:
- A constructor new()
- set_attr(name => value)
- get_attr(name)
can be used as the Namespace class.
The default one is Getopt::ArgParse::Namespace. It uses autoload to provide a readonly accessor method using dest names to access parsed values. [...]
What's a dest name, I hear you ask? You can specify them for options when calling add_arg by passing in an appropriate parameter, e.g. dest => 'count'; if you don't, "the name or the first option without leading dashes will be used as the name for retrieving values".
So all in all -- if you're intending to get fancy with this module, just use
$args->count;
after parsing, or alternatively
$ap->namespace->count;
and hopefully this should work as expected.
| [reply] [d/l] [select] |
I'd never used it before, but it looks like you need to access a value like this:
print $args->c, "\n";
Tip #4 from the Basic debugging checklist: Data::Dumper
use Data::Dumper;
$Data::Dumper::Sortkeys=1;
print Dumper($args);
# outputs...
$VAR1 = bless( {
'-values' => {
'c' => '10',
'current_command' => undef,
'f' => 0,
'help' => 0,
'no_f' => 1,
'no_help' => 1
}
}, 'Getopt::ArgParse::Namespace' );
Note: your code does not compile. | [reply] [d/l] [select] |