0

How can i parse all the arbitrary arguments to a hash without specifying the argument names inside my perl script.

Running command with below argument should give hash like below.

-arg1=first --arg2=second -arg3 -arg4=2.0013 -arg5=100

    {
      'arg2' => 'second',
      'arg1' => 'first',
      'arg4' => '2.0013',
      'arg3' => 1,
      'arg5' => 100
    };

This can be achieved using Getopt::Long as below

 GetOptions(\%hash,
    "arg1=s",
    "arg2=s",
    "arg3",
    "arg4=f",
    "arg5=i");

However, my argument list is too long and i don't want to specify argument names in GetOptions. So a call to GetOptions with only hash as a parameter should figure out what arguments are (and their type integer/string/floats/lone arguments) and just create a hash.

Pungs
  • 2,432
  • 1
  • 16
  • 14
  • 5
    If your argument list is long, then this is EXACTLY the time that you should want to specify all the acceptable arguments in `GetOptions`. Let it do the error checking for you, otherwise you're costing yourself a lot of potential grief in the future. – Miller Apr 09 '14 at 03:41
  • Actually bigger purpose is for writing a wrapper script to do argument processing/import default packages and call main function for every script. – Pungs Apr 09 '14 at 03:48

3 Answers3

2

There are a lot of Getopt modules. The following are some that will just slurp everything into a hash like you desire:

I personally would never do something like this though, and have no real world experience with any of these modules. I'd always aim to validate every script for both error checking and as a means to self-document what the script is doing and uses.

Miller
  • 34,962
  • 4
  • 39
  • 60
1

Try this:

#!/usr/bin/perl

use warnings;
use strict;

use Data::Dumper;

sub getOptions {
    my (%opts, @args);
    while (@_) {
        my $opt = shift;
        if ($opt =~ /^-/) {
            if ($opt =~ /-+([^=]+)(?:=(.+))?/) {
                $opts{$1} = $2 ? $2 : 1;
            }
        }
        else {
            push @args, $opt;
        }
    }

    return (\%opts, \@args);
}

my ($opts, $args) = getOptions(@ARGV);

print Dumper($opts, $args);

Testing:

$ perl t.pl -arg1=first --arg2=second -arg3 -arg4=2.0013 -arg5=100 datafile
$VAR1 = {
          'arg2' => 'second',
          'arg1' => 'first',
          'arg4' => '2.0013',
          'arg3' => 1,
          'arg5' => '100'
        };
$VAR2 = [
          'datafile'
        ];
Lee Duhem
  • 14,695
  • 3
  • 29
  • 47
1

This will work as expected for your example,

my %hash = map { s/^-+//; /=/ ? split(/=/, $_, 2) : ($_ =>1) } @ARGV;
mpapec
  • 50,217
  • 8
  • 67
  • 127