Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Getopt::Long mystery

by Llew_Llaw_Gyffes (Scribe)
on Aug 17, 2005 at 22:03 UTC ( [id://484618]=perlquestion: print w/replies, xml ) Need Help??

Llew_Llaw_Gyffes has asked for the wisdom of the Perl Monks concerning the following question:

I have a Perl script which begins as follows:

#!/usr/bin/perl use strict; use Getopt::Long; my (%opt); Getopt::Long::Configure ("bundling"); if (GetOptions(\%opt, 'digits=i', 'help|usage|?', 'quiet', 'reverse', 'separator=s', 'test|n', 'verbose', 'zero|0')) {

In this script, and ONLY this script, Getopt::Long fails.  In every other script I have, it's working perfectly.  Invoking the above script with a sample command line yields:

babylon5:alaric:/minbar/camera/canon/test:39 $ renum -t foo img* Unknown option: t

I'm baffled.  I've rewritten the entire top of the file by hand in case somehow the file has become corrupted with some invisible character.  I can see nothing wrong with it, but I can't make it work, and no other Getopt::Long-using script on my system breaks the same way.  If I remove the call to Getopt::Long::Configure, the GetOptions call recognizes options again, but of course option bundling no longer works.  If I write a new script from scratch comprising nothing but a call to Getopt::Long and the necessary declarations, it fails in the same way; yet every other existing script using Getopt::Long and Getopt::Long::Configure("bundling") continues to work.

Can anyone some up with any theory, however wild, to explain what's going on, or point out some error in the code that I've somehow missed?

Update:

It was not clear from the example above that ALL options are unrecognized, not just -t.  To clarify, if I comment out the bundling configuration, I can do the following:

babylon5:alaric:~:1 $ renum -t -d 4 foo bar* Test mode: No changes will be committed Trying pattern: bar\* Using format foo-%04d.jpg No files found; doing nothing

Now, if I re-enable the Configure call and issue the exact same command:

babylon5:alaric:~:2 $ renum -t -d 4 -r foo bar* Unknown option: t Unknown option: d Unknown option: r Usage: renum [options] pattern files Options: -d digits Use <digits> digits in ordinal field -zero, -0 Begin numbering from 0 (default 1) -quiet Quiet (no progress messages) -reverse Reverse order -separator <char> Use <char> as separator character (default +'-') -test, -n Do not make any actual changes All options may be abbreviated.

In subsequent messing with this, I've discovered that I can make it recognize the command line options again by explicitly specifying the appreviations I want to be accepted.  It is possible I have misunderstood the documentation on the module.  The documentation states:

Without additional configuration, GetOptions() will ignore the case of option names, and allow the options to be abbreviated to uniqueness.

Now, the interaction between bundling and ignore-case is documented, but NOWHERE IS IT SPECIFICALLY STATED that setting any particular configuration option (bundling, for example) disables the automatic abbreviation.  It appears, however, with further examination, that this is what's happening:  if bundling is enabled, automatic abbreviation of command-line options is silently disabled.  What's more, there appears to be no mechanism for re-enabling it.

Can anyone confirm that this behavior is in fact intentional?  If so, it really should be documented.

Replies are listed 'Best First'.
Re: Getopt::Long mystery
by DrWhy (Chaplain) on Aug 17, 2005 at 22:57 UTC
    When you turn bundling on you have to use double dashes (--) on long options names, even if you are abbreviating them to a single character. Try using --t instead of -t. If that doesn't work, try --test.

    --DrWhy

    "If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."

Re: Getopt::Long mystery
by DrWhy (Chaplain) on Aug 18, 2005 at 02:18 UTC
    Now, the interaction between bundling and ignore-case is documented, but NOWHERE IS IT SPECIFICALLY STATED that setting any particular configuration option (bundling, for example) disables the automatic abbreviation.
    Abbreviation is not disabled with bundling. Abbreviation always applies only to 'long' (more than single character) options. Without bundling turned on, the module is looser about when it treats an option as a long option. Without bundling, -t may be a single letter option or an abbreviated long option.

    With bundling turned on options beginning with a single '-' are treated as single character options exclusively. If you want to get the auto-abbreviation behavior of long names under bundling you must start the option with two '-'s. This is explicitly stated in the documentation.

    --DrWhy

    "If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."

      With bundling turned on options beginning with a single '-' are treated as single character options exclusively. If you want to get the auto-abbreviation behavior of long names under bundling you must start the option with two '-'s. This is explicitly stated in the documentation.

      Aaaah.... That explains the behavior.  So, if one wishes to abbreviate the 'test' option to t with bundling enabled, one must somewhat counter-intuitively use '--t' instead of '-t'.  This was not clear to me from the documentation.

      I see, incidentally, that this remains true even with bundling_override set, which eliminates the double-dash requirement for long options, but evidently not for abbreviations thereof....

Re: Getopt::Long mystery
by Roger (Parson) on Aug 17, 2005 at 22:18 UTC
    Have you declared the -t option in the first place? Perhaps changing 'test|n' to 'test|t' will do the trick? :-)

    Update
    Forget about what I said above. I don't think that's what you are asking about.

      Abbreviation should still work, no?  I'm using 'test|n' to make '-n' a synomym for '-t'.  An example with a more extensive set of options employed (which, perhaps, I should put in there instead as illustration) will show that not just the -t option, but ALL options, are unrecognized.

      I'll update the example.

Re: Getopt::Long mystery
by trammell (Priest) on Aug 17, 2005 at 22:23 UTC
    Perhaps you should add option 't' to your opt list.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://484618]
Approved by shenme
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2024-03-28 22:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found