문제

I am writing a script that can do something like:

script-name --resource1=xxx --resource2=xxx

But this can go up to 50+. Is there a way to make GetOpt accept dynamic option names?

도움이 되었습니까?

해결책

What about auto-generating the options list for Getopt::Long like example below? Since the list of options will be likely pretty long, using Getopt::ArgvFile allow you to supply configuration file with options instead of specifying them on command-line.

use Getopt::Long;
use Getopt::ArgvFile;
use Data::Dump;

my @n = (1 .. 10);    # how many resources allowed
my %opts = (
    port                  => ':i',
    http_version          => ':s',
    invert_string         => ':s',
    ssl                   => '',
    expect                => ':s',
    string                => ':s',
    post_data             => ':s',
    max_age               => ':i',
    content_type          => ':s',
    regex                 => ':s',
    eregi                 => ':s',
    invert_regex          => '',
    authorization         => ':s',
    useragent             => ':s',
    pagesize              => ':s',
    expected_content_type => ':s',
    verify_xml            => '',
    rc                    => ':i',
    hostheader            => ':s',
    cookie                => ':s',
    encoding              => ':s',
    max_redirects         => ':i',
    onredirect_follow     => ':i',
    yca_cert              => ':s',
);

my %args = ();
GetOptions(\%args,
    map {
        my $i = $_;
        ( "resource$i:s", map { "resource${i}_$_$opts{$_}" } keys %opts )
    } @n
) or die;

dd \%args;

다른 팁

Would it work with the same option name repeated?

For example: script-name --resource=xxx --resource=xxx

Yes, as I just figured out how to do it myself as I wanted to accept a -# argument and Getopt::Long doesn't accept regex for an option name. So this is what I did:

use Getopt::Long qw(:config pass_through);

my $ret=GetOptions(
    \%gops,
    'lines|l',  # lines/records to display
    ... cut ...
    '<>' => \&filearg,          # Handle file names also attach current options
);

I then defined the filearg() function:

sub filearg {
    my $arg=shift;

    # First see if it is a number as in -20 as shortcut for -l 20
        if ($arg =~ /^--?(\d)+$/) {
        $gops{'lines'}=$1;
    } elsif (-f "$arg" && -r "$arg") {
        my %ops=%gops;
        $fops{$arg}=\%ops;
        push(@files, $arg);
    } else {
        push(@badargs, $arg);
    }
    return(undef);
}

So what is needed is the pass_through option, a check for what you want and setting those things when seen. Above I had undefined options passed to my function. I use this for file checks and for a special option -# where # is some integer. If it doesn't match I add to a badargs array, as doing this will not cause GetOptions to fail, so I have to check this array after the return from GetOptions to see if errors were seen. You can also have it end on option error by ending the callback function with die("!FINISH"); which will cause GetOptions to terminate the script.

What I use it for is the ability to have something like -20 FILE1 -30 FILE2, so options can be overridden for subsequent files. I see you being able to do something similar with a check for the first part of the option name and then the value. So if all of your options start with --resource then look for something like this in your function: /^--?(resource\w+)=(.*)$/ and then add into option array.

Anyway, hope this helps.

Another method to try would be to just use some sort of configuration file. It seems like this might be the easiest method to both write and parse, given that you plan on having a large amount of information.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top