parsing unknown options

Discussion in 'Ruby' started by Stefano Crocco, Nov 13, 2006.

  1. I'm not a ruby expert, so forgive me if the answer to my question is
    obvious. I want to write a program which will load a plug-in
    depending on an option passed in the command line. Each of the possible
    plug-ins have their own options, which will also need to be parsed. For
    example, if the main application accepts the -p option to select the
    plug-in and the -a and -b options, I would like my program to be called
    this way:

    program -p myplugin -a -b -c -d

    of course -c and -d are the options recognized by the plug-in. I'm not
    sure on how to implement this. My initial idea was to use a two steps
    approach:
    1: parse the command line arguments looking only for the -p options and
    ignoring the others. Once found the name of the plug-in, load it.
    2: parse again the arguments, this time considering all the options,
    including those accepted by the plug-in (which the plug-in itself will
    tell the main program in some way).

    The problem is that, as far as I can tell, OptParse will raise an
    exception when it finds an unknown option (i.e as soon as it hits -c in
    my example above). Is there a way around this behavior? Or does anybody
    know of a better way to approach the whole problem?

    Thanks in advance

    Stefano

    --
    Posted via http://www.ruby-forum.com/.
    Stefano Crocco, Nov 13, 2006
    #1
    1. Advertising

  2. Paul Lutus wrote:
    > Stefano Crocco wrote:

    ...
    >> The problem is that, as far as I can tell, OptParse will raise an
    >> exception when it finds an unknown option (i.e as soon as it hits -c in
    >> my example above). Is there a way around this behavior? Or does anybody
    >> know of a better way to approach the whole problem?

    >
    > Sure. Parse the command line yourself.


    I don't recommend it unless your syntax is simple or you like writing
    command line parsers.

    It just so happens that yesterday I wrote a command line parser that may
    help in this case. I wrote it because getopt/long wasn't deleting option
    arguments from ARGV, so it was hard to use with ARGF. My parser leaves
    any unknown options it finds in ARGV. It has some other nice features[1]
    and only a few limitations[2]. Basically, it does one thing: turn an
    array of strings into a hash of recognized options and their arguments,
    leaving unrecognized strings in the original array.

    I didn't plan on releasing this today, but there's really no reason not
    to. It's called argos[3]. For now it lives at:

    http://redshift.sourceforge.net/argos.rb

    The heart of it is simple enough (about 40 lines) to copy and paste into
    a small ruby program file, if you don't want to require it as a library.

    Here's a simple example:

    require 'argos'

    optdef = {
    "v" => true,
    "n" => proc {|arg| Integer(arg)}
    }

    argv = %w{-v -n10 filename}
    opts = Argos.parse_options(argv, optdef)
    p opts # ==> {"v"=>true, "n"=>10}
    p argv # ==> ["filename"]

    [1] Features:

    Output is a hash of {option => value, ...}.

    Supports both long ("--foo") and short ("-f") options.

    A long option with an argument is --foo=bar or --foo bar.

    A short option with an argument is -fbar or -f bar.

    The options -x and --x are synonymous.

    Short options with no args can be combined as -xyz in place of
    -x -y -z.

    The string "--" terminates option parsing, leaving the rest
    untouched.

    [2] Limitations:

    A particular option takes either 0 args or 1 arg. There are no
    optional arguments, in the sense of both "-x" and "-x3" being
    accepted.

    Options lose their ordering in the output hash (but they are
    parsed in order and you can keep track using state in the handler
    closures).

    There is no usage/help output.

    [3] Argos was Odysseus' faithful dog, who was good at recognizing ;)

    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
    Joel VanderWerf, Nov 14, 2006
    #2
    1. Advertising

  3. Thanks for the answers. I decided to take an approach similar to
    building my own parser, but keeping my two steps approach:
    - first:

    ARGV.each_with_index do |s, i|
    plugin=args[i+1] if s=='-p' or s=='--plugin' or s=~/-\w*p/
    end

    (this should take care of the three possible formats: short option, long
    option and several short options together, such as -abp plugin

    - load the plugin
    - use OptionParser to rescan the options

    I'm still working on how to communicate the options recognized by the
    plugin to the main program.

    Stefano

    --
    Posted via http://www.ruby-forum.com/.
    Stefano Crocco, Nov 14, 2006
    #3
  4. Stefano Crocco

    Guest

    On Tue, 14 Nov 2006, Stefano Crocco wrote:

    > Thanks for the answers. I decided to take an approach similar to
    > building my own parser, but keeping my two steps approach:
    > - first:
    >
    > ARGV.each_with_index do |s, i|
    > plugin=args[i+1] if s=='-p' or s=='--plugin' or s=~/-\w*p/
    > end
    >
    > (this should take care of the three possible formats: short option, long
    > option and several short options together, such as -abp plugin
    >
    > - load the plugin
    > - use OptionParser to rescan the options
    >
    > I'm still working on how to communicate the options recognized by the
    > plugin to the main program.
    >
    > Stefano


    OptionParser already handles unknown options:

    begin
    option_parser.parse! argv
    rescue OptionParser::InvalidOption => e
    # preverve unknown options
    e.recover argv
    end


    -a
    --
    my religion is very simple. my religion is kindness. -- the dalai lama
    , Nov 14, 2006
    #4
  5. unknown wrote:
    > On Tue, 14 Nov 2006, Stefano Crocco wrote:
    >
    >>
    >> - load the plugin
    >> - use OptionParser to rescan the options
    >>
    >> I'm still working on how to communicate the options recognized by the
    >> plugin to the main program.
    >>
    >> Stefano

    >
    > OptionParser already handles unknown options:
    >
    > begin
    > option_parser.parse! argv
    > rescue OptionParser::InvalidOption => e
    > # preverve unknown options
    > e.recover argv
    > end
    >
    >
    > -a


    Thanks for pointing this out. It's exactly what I was looking for, and I
    completely missed it. I've modified your code to store in a array the
    unrecognized options and their arguments, if any is provided:

    unknown=[] #this is the array where the unknown options will be put

    begin
    option_parser.parse! argv
    rescue OptionParser::InvalidOption => e
    e.recover argv
    #recover just put the unknown option back into argv, so I extract it
    again and put it into unknown
    unknown << argv.shift

    #if argv still contains some elements, and the first one doesn't start
    with a -, i.e is the argument for the unknown option, I remove it as
    well
    unknown << argv.shift if argv.size>0 and temp.first[0..0]!='-'
    # go on with parsing
    retry
    end

    puts unknown


    --
    Posted via http://www.ruby-forum.com/.
    Stefano Crocco, Nov 14, 2006
    #5
  6. On 14.11.2006 18:19, wrote:
    > On Tue, 14 Nov 2006, Stefano Crocco wrote:
    >
    >> Thanks for the answers. I decided to take an approach similar to
    >> building my own parser, but keeping my two steps approach:
    >> - first:
    >>
    >> ARGV.each_with_index do |s, i|
    >> plugin=args[i+1] if s=='-p' or s=='--plugin' or s=~/-\w*p/
    >> end
    >>
    >> (this should take care of the three possible formats: short option, long
    >> option and several short options together, such as -abp plugin
    >>
    >> - load the plugin
    >> - use OptionParser to rescan the options
    >>
    >> I'm still working on how to communicate the options recognized by the
    >> plugin to the main program.
    >>
    >> Stefano

    >
    > OptionParser already handles unknown options:
    >
    > begin
    > option_parser.parse! argv
    > rescue OptionParser::InvalidOption => e
    > # preverve unknown options
    > e.recover argv
    > end


    Thanks! Learn something new every day. I believe OptionParser to be an
    excellent piece of software - actually this short example is just
    another confirmation for that. But I always found that documentation of
    OptionParser was a bit weak. Did I miss anything? Clearly the docs on
    ruby-doc.org are rudimentary. Is there anyone that knows OptionParser
    intimately and is willing to write up some documentation or at least add
    some more examples to doc of class OptionParser that demonstrate
    additional funcationality? It might be sufficient to just collect
    working pieces of OptionParser code from the community, massage it a bit
    and place it into the default docs. I would greatly appreciate that -
    and probably others, too. What do you think?

    Kind regards

    robert
    Robert Klemme, Nov 15, 2006
    #6
  7. [was parsing unknown options] OptionParser documentation improvements

    Robert Klemme wrote:
    > On 14.11.2006 18:19, wrote:
    >> On Tue, 14 Nov 2006, Stefano Crocco wrote:
    >>
    >>> Thanks for the answers. I decided to take an approach similar to
    >>> building my own parser, but keeping my two steps approach:
    >>> - first:
    >>>
    >>> ARGV.each_with_index do |s, i|
    >>> plugin=args[i+1] if s=='-p' or s=='--plugin' or s=~/-\w*p/
    >>> end
    >>>
    >>> (this should take care of the three possible formats: short option, long
    >>> option and several short options together, such as -abp plugin
    >>>
    >>> - load the plugin
    >>> - use OptionParser to rescan the options
    >>>
    >>> I'm still working on how to communicate the options recognized by the
    >>> plugin to the main program.
    >>>
    >>> Stefano

    >>
    >> OptionParser already handles unknown options:
    >>
    >> begin
    >> option_parser.parse! argv
    >> rescue OptionParser::InvalidOption => e
    >> # preverve unknown options
    >> e.recover argv
    >> end

    >
    > Thanks! Learn something new every day. I believe OptionParser to be an
    > excellent piece of software - actually this short example is just
    > another confirmation for that. But I always found that documentation of
    > OptionParser was a bit weak. Did I miss anything? Clearly the docs on
    > ruby-doc.org are rudimentary. Is there anyone that knows OptionParser
    > intimately and is willing to write up some documentation or at least add
    > some more examples to doc of class OptionParser that demonstrate
    > additional funcationality? It might be sufficient to just collect
    > working pieces of OptionParser code from the community, massage it a bit
    > and place it into the default docs. I would greatly appreciate that -
    > and probably others, too. What do you think?


    I think that it would be a great idea. Personnaly, I always found that
    looking at the code, documentation and trying was enough, but with
    appropriate examples, that would be a lot easier. If the current
    maintainers of OptionParser are reading this, that would be nice to tell
    us how we could contribute to this ?

    Would it make sense to put that documentation on a personal page,
    waiting to be included upstream ? I'd be willing to do that, if anyone
    wants to contribute.

    Cheers !

    Vince

    --
    Vincent Fourmond, PhD student
    http://vincent.fourmond.neuf.fr/
    Vincent Fourmond, Nov 15, 2006
    #7
  8. On Wed, Nov 15, 2006 at 06:05:08PM +0900, Robert Klemme wrote:
    > Thanks! Learn something new every day. I believe OptionParser to be an
    > excellent piece of software - actually this short example is just
    > another confirmation for that. But I always found that documentation of
    > OptionParser was a bit weak. Did I miss anything? Clearly the docs on
    > ruby-doc.org are rudimentary. Is there anyone that knows OptionParser
    > intimately and is willing to write up some documentation or at least add
    > some more examples to doc of class OptionParser that demonstrate
    > additional funcationality? It might be sufficient to just collect
    > working pieces of OptionParser code from the community, massage it a bit
    > and place it into the default docs. I would greatly appreciate that -
    > and probably others, too. What do you think?


    I've been using OptionParser a fair bit. You can count me in if you
    want to coordinate something. I'll go through my code and pull out some
    examples too.

    enjoy,

    -jeremy

    --
    ========================================================================
    Jeremy Hinegardner
    Jeremy Hinegardner, Nov 15, 2006
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Cliff  Martin
    Replies:
    1
    Views:
    3,022
    Larry Smith
    Jan 31, 2007
  2. jacksu
    Replies:
    0
    Views:
    498
    jacksu
    Oct 9, 2007
  3. Utkado
    Replies:
    2
    Views:
    2,062
  4. Vincent Arnoux
    Replies:
    1
    Views:
    236
    Arnaud Bergeron
    Aug 11, 2006
  5. Gary Rutledge

    unknown regexp options

    Gary Rutledge, Sep 29, 2010, in forum: Ruby
    Replies:
    8
    Views:
    273
Loading...

Share This Page