optparse question: how to warn of missing positional arguments

Hello,

My goal is to force a display of the banner (usage string) when a
positional parameter is not present; in the sense of ARGV[1] == nil

An possible way would be to force the OptionParse.new block parse to fail
if ARGV[1] == nil. How to do this properly in Ruby?

I love Ruby so much! Thx all!
az

An possible way would be to force the OptionParse.new block parse to fail if ARGV[1] == nil. How to do this properly in Ruby?

Printing the option block arg and exiting non-zero should suffice:

OptionParser.new do |o|
  if args.empty? then
    puts o
    exit 1
  end
end.parse! args

outputs something like:

···

On Mar 22, 2019, at 12:48, Artie Ziff <artie.ziff@gmail.com> wrote:

Usage: irb [options]

After the option parser has completed parsing arguments, it will leave any
non-option arguments in the argument array. You can check that the array
is empty and then print the help message and exit. The key is to preserve
a reference to the parser object so that you can call #to_s on it later to
emit the usage output when needed. Below is an example largely lifted from
the documentation for the optparse library which will do what I believe you
are asking about:

example.rb

···

-------------------------------------------
require 'optparse'

option = false

parser = OptionParser.new do |opts|
  opts.banner = 'Usage example.rb [options] REQUIRED_ARG'
  opts.separator ''

  opts.on('-a', '--an-option', 'An example option') do |val|
    option = val
  end

  opts.on('-h', '--help', 'Prints this help') do
    puts opts
    exit
  end
end
parser.parse!

if ARGV.empty?
  puts parser
  exit 1
end

p option
p ARGV

-Jeremy

On Fri, Mar 22, 2019 at 2:49 PM Artie Ziff <artie.ziff@gmail.com> wrote:

Hello,

My goal is to force a display of the banner (usage string) when a
positional parameter is not present; in the sense of ARGV[1] == nil

An possible way would be to force the OptionParse.new block parse to fail
if ARGV[1] == nil. How to do this properly in Ruby?

I love Ruby so much! Thx all!
az

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Hi Jeremy,

This example really help wrap my head around the moving parts.
In fact, I am able to omit the block: opts.on('-h')

And just changed the test condition with ARGV to be less than a particular
count of ARGs.

Many thanks for showing where to put everything so that it is well
organized.

-az

I wouldn’t. The main difference is `exit 0` vs `exit 1`.

···

On Mar 22, 2019, at 15:26, Artie Ziff <artie.ziff@gmail.com> wrote:

This example really help wrap my head around the moving parts.
In fact, I am able to omit the block: opts.on('-h’)

I do not think it is possible to ever get into that situation except
for messing with ARGV in the ruby program. If you do not do that there
will never be Nil in ARGV. Or are you talking about ARGV being too
short? In that case, there are two situations

1. a mandatory arg is missing for an option, then OptionParser will
flag this anyway.
2. a mandatory non option argument is missing, then you just check for
empty ARGV (or generally the length of ARGV) and flag this as error
outside of OptionParser processing.

Kind regards

robert

···

On Fri, Mar 22, 2019 at 8:49 PM Artie Ziff <artie.ziff@gmail.com> wrote:

My goal is to force a display of the banner (usage string) when a positional parameter is not present; in the sense of ARGV[1] == nil

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/

I totally overlooked that nil… Yeah. there won’t be a nil, but there might be an empty string. If that’s what you’re checking for, then you can raise InvalidArgument in the handling block (or write a converter? I’ve never needed/bothered to do that). See parse_arg in optparse.rb.

···

On Apr 2, 2019, at 07:17, Robert Klemme <shortcutter@googlemail.com> wrote:

On Fri, Mar 22, 2019 at 8:49 PM Artie Ziff <artie.ziff@gmail.com> wrote:

My goal is to force a display of the banner (usage string) when a positional parameter is not present; in the sense of ARGV[1] == nil

I do not think it is possible to ever get into that situation except
for messing with ARGV in the ruby program. If you do not do that there
will never be Nil in ARGV. Or are you talking about ARGV being too
short? In that case, there are two situations

1. a mandatory arg is missing for an option, then OptionParser will
flag this anyway.
2. a mandatory non option argument is missing, then you just check for
empty ARGV (or generally the length of ARGV) and flag this as error
outside of OptionParser processing.

Some cases of malformed arguments are handled by declaring the
argument type (i.e. you can specify that something must be an
integer). It might even be possible to provide a custom regular
expression or a list of allowed values.

Kind regards

robert

···

On Wed, Apr 3, 2019 at 1:55 AM Ryan Davis <ryand-ruby@zenspider.com> wrote:

> On Apr 2, 2019, at 07:17, Robert Klemme <shortcutter@googlemail.com> wrote:
>
> On Fri, Mar 22, 2019 at 8:49 PM Artie Ziff <artie.ziff@gmail.com> wrote:
>
>> My goal is to force a display of the banner (usage string) when a positional parameter is not present; in the sense of ARGV[1] == nil
>
> I do not think it is possible to ever get into that situation except
> for messing with ARGV in the ruby program. If you do not do that there
> will never be Nil in ARGV. Or are you talking about ARGV being too
> short? In that case, there are two situations
>
> 1. a mandatory arg is missing for an option, then OptionParser will
> flag this anyway.
> 2. a mandatory non option argument is missing, then you just check for
> empty ARGV (or generally the length of ARGV) and flag this as error
> outside of OptionParser processing.

I totally overlooked that nil… Yeah. there won’t be a nil, but there might be an empty string. If that’s what you’re checking for, then you can raise InvalidArgument in the handling block (or write a converter? I’ve never needed/bothered to do that). See parse_arg in optparse.rb.

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/