in reply to parsing arguments

Perhaps I'm totally off base, but if your just looking for a simple hash $hash{$key}=$value; for each option, this should be fairly easy to do.

Since all of the args are automatically split by the shell, the hardest part is out of your way. All should have to do is this:
my %hash; for(@ARGV) { my($key,$val) = split/=/,$_,2; $hash{$key}=$val; } use Data::Dumper; print Dumper(\%hash); __END__ Output: $VAR1 = { 'vchtyp' => 'I', 'jrnltyp' => 'D', 'title' => '\'this is a title\'', 'lexwhere' => '\'in(\'DIS\', \'DIM\', \'DIR\')\'' }; (Data::Dumper is inserting those extraneous backslashes, ignore them)
Now if you wanted to parse some values into more complicated data structures then just scalars, well, it gets slightly more complicated. For example, the lexwhere key. You might be able to get away with something like:
my @vals = $hash{lexwhere}=~/'([^'])'/;
But thats really fragile and requires having strict controls over what gets passed to your script. (in fact, it's so fragile it doesn't even work on the data as presented, you'll need to munge off the beginning and ending single quotes)

Replies are listed 'Best First'.
Re: Re: parsing arguments
by mifflin (Curate) on Oct 07, 2003 at 23:53 UTC
    Your right!
    I looks like if you quote all the values correctly ARGV seems to get it right.
    I didn't know perl was so smart :-)
    thanks
      It's actually the shell that is so smart. Pretty much any language (at least, any with some form of ARGV-like construct) is going to parse it correctly. You see, the shell doesn't pass your program the character string from the command line, rather the shell passes your program an array of parameter strings.

      This is why if you look at system(...) or exec(...), you see that they take a list as their argument (or, again, whatever parallel construct in any other language). You also see that if you only pass one item in that list, and it contains characters which the shell will know how to handle, that perl actually invokes the shell to handle converting that string into the @ARGV of the sub-process.


      ------------
      :Wq
      Not an editor command: Wq
Re: Re: parsing arguments
by mifflin (Curate) on Oct 08, 2003 at 15:46 UTC
    I'm not sure why this is true, but on my system, Sun Solaris using ksh, I must also escape the spaces. If I don't @ARGV gets broken up along those spaces too. This is probably because I am executing my perl script from a ksh script, not from the command line. Somehow running my perl script in ksh from a ksh script changes things?
      This is because the parsing of your command-line string is done by the shell, not by perl. Different shells have slightly different rules for parsing the command line into argv. (More correctly, different shells have slightly different rules for how they expect the user to represent argv as a string.) It's just convention that most shells use very similar rules for this. (Typically, separate parameters by spaces which are not enclosed in apostrophes or quotes, and which are not preceeded by a single backslash.)

      Try this

      perl -MData::Dumper -e "print Dumper(\@ARGV).qq{\n}" a b c 'a b c' a\ +b\ c "a b c" "'a b c'" *
      under different shells and you may get slightly different results. It's really interesting to see the difference under windows/DOS command.com or cmd.exe shells, because the asterisk at the end of the line is just taken as a literal asterisk, whereas under unix shells, the asterisk will, instead, be replaced by the list of all files and directories matching the wildcard. In DOS/windows, programs that might operate on many files interpret the asterisk themselves, whereas in unix, the asterisk is transformed by the shell. For a really simple comparison, just try:
      echo *
      on both systems.

      Anyways, for really detailed information on how your various shells parse the command line into argv, you should read that shell's documentation (man page).


      ------------
      :Wq
      Not an editor command: Wq