Re: getting args without clobbering @ARGV
by revdiablo (Prior) on May 11, 2006 at 18:48 UTC
|
I have used Getopt::Long for years, and it doesn't seem very "clunky and difficult to manage", but it could just be me. Here's how I'd do that:
use Getopt::Long;
my $debug = 0;
# Optional parameters (removed from @ARGV)
GetOptions(
'debug' => \$debug,
);
# Positional parameters (left in @ARGV)
my ($infile) = @ARGV;
Update: replaced code ref with simple scalar ref to flag variable
Update: a few minor points:
- Getopt::Std certainly is clunky, but Getopt::Long has been included as a standard module since 5.003_07, which was released almost 10 years ago.
- Getopt::Long will allow shortening of '--debug' down to '-d' by default. That said, it is often preferable to list these more explicitly, as Xaositect has demonstrated.
| [reply] [d/l] |
|
Thanks for the suggestion and for the sample code.
For me I guess "clunky and difficult to manage" comes from the Camel book, pages 452-453 where, using getops you have something like:
my $debug = 0;
getopt('dlv');
if ($opt_d) {
$debug = 1;
}
if ($opt_l) {
# do something with arg l
}
if ($opt_v) {
# do something with arg v
}
To me that is not very managable. I can see from your code example and from the CPAN docs for Getopt::Long that this might actually be more workable for me.
I presume that I have to set some sort of option to be able to use "-d" rather than "-debug"?
| [reply] [d/l] |
|
GetOptions(
'debug|d' => \$debug,
);
Xaositect - Whitepages.com
| [reply] [d/l] |
Re: getting args without clobbering @ARGV
by davido (Cardinal) on May 11, 2006 at 18:51 UTC
|
Clunky as it may be, this is where Getopt::Long excels. With Getopt::Long, the -hyphenated options can be processed, while leaving non-hyphenated (such as filenames) untouched in @ARGV.
Actually, after you use Getopt::Long a few times I think you'll gain enough familiarity with it that you'll no longer consider it too clunky.
| [reply] |
Re: getting args without clobbering @ARGV
by GrandFather (Saint) on May 11, 2006 at 18:46 UTC
|
Change the while (@ARGV) {$arg = shift @ARGV; to for $arg (@ARGV) {.
Note though that $arg is aliased to each of the elements of @ARGV in turn so if you change the contents of $arg inside the for loop you will change the contents of @ARGV.
DWIM is Perl's answer to Gödel
| [reply] [d/l] [select] |
|
While I agree with quite about everyone else's opinion that, say, Getopt::Long is very far from being "very clunky and difficuly to manage" and that the OP should better use some Getopt::* module, ++your answer since what is most awkward in his code is the bizarre flow control. Well worth then to point out that the "canonical" way to iterate over an array (or more generally, a list) is a for cycle - unless one has very special needs.
To this, for the benefit of the OP, I would only add that if he has whatever code that "clobbers" an array, and if this is undesirable, then copying it to another array and working on the latter is certainly possible. Well, it may not be sensible if the starting array is huge, but that can hardly be the case for @ARGV. In this case, as in many others, though it is better not to clobber it in the first place...
| [reply] [d/l] [select] |
Re: getting args without clobbering @ARGV
by ioannis (Abbot) on May 11, 2006 at 19:59 UTC
|
While previous posts prop better suggestions, another way is
to declare @ARGV with local in a block so it
reclaims the old values when it exits the block.
As shown bellow, add lines #7, #8, and 19 to the old code:
my $arg;
my $argcount = 0;
my $debug = 0;
my $infile;
#line 7
{
#line 8
local @ARGV = @ARGV;
while (@ARGV) {
$arg = shift @ARGV;
if ($arg =~ /-d/) {
$debug = 1;
} elsif ($argcount == 0) {
$infile = $arg;
}
}
#line 19
}
| [reply] [d/l] |
Re: getting args without clobbering @ARGV
by smokemachine (Hermit) on May 11, 2006 at 19:07 UTC
|
perl -e 'for(0..$#ARGV){($debug,$infile)=(1,$ARGV[$_+1]) if $ARGV[$_]=
+~/-d/}'
| [reply] [d/l] |
Re: getting args without clobbering @ARGV
by BrowserUk (Patriarch) on May 11, 2006 at 20:16 UTC
|
For simple scripts, perl's -s option may be all you need. See perlrun for details;
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
Re: getting args without clobbering @ARGV
by graff (Chancellor) on May 12, 2006 at 02:49 UTC
|
An idiom I use a lot for quickie ad-hoc scripts with really simple option stuff:
# really simple:
my $debug = ( @ARGV and $ARGV[0] eq '-d' ) ? shift : '';
# or, more in the style of getopt:
my %opt;
while ( @ARGV and $ARGV[0] =~ /^-([dv])$/ ) {
$opt{$1} = 1;
shift;
}
But for anything more elaborate, I take the time to recheck the usage for Getopt::Std or Getopt::Long (can't seem to memorize it, but I've gotten better at locating my favorite parts of those man pages) -- it ends up quicker, cleaner and easier to maintain than not using one of those modules. | [reply] [d/l] |