[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Strange behaviour in OptionParser class

Hunter Kelly

3/8/2005 3:15:00 PM

If I run the following:

#!/usr/bin/ruby -w

require 'optparse'

$host = "localhost"
$user = nil
$db = nil

opts = OptionParser.new
opts.on("-h", "--host", "=HOST", "hostname") { | h | $host = h }
opts.on("-u", "--user", "=USER", "username") { | u | $user = u }
opts.on("--db=DATABASE", "database") { | db | $db=db }

words=%w(--user --host=hostname --db=dbname blah blah blah)
rest = opts.parse(*words)

puts "user: #{$user} rest: #{rest.join(',')} host: #{$host} db:
#{$db}"

------

I get the following output:

user: --host=hostname ok: blah,blah,blah host: localhost db: dbname

I would think that this should generate some form of error: if an
option has a mandatory argument, it doesn't really make sense to me to
blithely assign the next argument - particularly in this case, where it
is obviously another option.

Am I correct in my thinking here, or did I miss something, or is this
just something that OptionParser doesn't support?

Thanks,

Hunter

3 Answers

Robert Klemme

3/8/2005 4:46:00 PM

0


"Hunter Kelly" <retnuh@gmail.com> schrieb im Newsbeitrag
news:1110294924.958223.50010@f14g2000cwb.googlegroups.com...
> If I run the following:
>
> #!/usr/bin/ruby -w
>
> require 'optparse'
>
> $host = "localhost"
> $user = nil
> $db = nil
>
> opts = OptionParser.new
> opts.on("-h", "--host", "=HOST", "hostname") { | h | $host = h }
> opts.on("-u", "--user", "=USER", "username") { | u | $user = u }
> opts.on("--db=DATABASE", "database") { | db | $db=db }
>
> words=%w(--user --host=hostname --db=dbname blah blah blah)
> rest = opts.parse(*words)
>
> puts "user: #{$user} rest: #{rest.join(',')} host: #{$host} db:
> #{$db}"
>
> ------
>
> I get the following output:
>
> user: --host=hostname ok: blah,blah,blah host: localhost db: dbname
>
> I would think that this should generate some form of error: if an
> option has a mandatory argument, it doesn't really make sense to me to
> blithely assign the next argument - particularly in this case, where it
> is obviously another option.
>
> Am I correct in my thinking here, or did I miss something, or is this
> just something that OptionParser doesn't support?

I think you missed something. :-) How do you want OP to detect whether
it's a valid option value or an option if it's a string field without
further speficiation? It might for example be an option of another
program that is invoked later so it's not uncommon to have options as
values of options.

Note, that you can use a regexp for validation if you want to prevent this
case:

opts.on("-u", "--user", "=USER", /[^-].*/, "username") { | u | $user = u }
opts.on("-u", "--user", "=USER", /\w+/, "username") { | u | $user = u }

Also, for numeric options you can use Integer etc. plus you can throw
OptionParser::InvalidArgument from the block or you define a criterium
like this:

crit = Object.new
def crit.match(o)
/^[^-]/ === o && [o]
end
....
opts.on("-u", "--user", "=USER", crit, "username") { | u | $user = u }

Any of these will happily throw with your command line. So there's plenty
of ways to do it if you want to be more restrictive... :-))

Kind regards

robert

Hunter Kelly

3/9/2005 9:41:00 AM

0

Yah, that's fair enough I suppse (It's what I ended up doing in the
end), but it seems to me that the default behaviour should be to not
match it if it looks like another option. For the special case of
options for another program (or whatever), then put in the special
matching objects or whatever.

I think for me, it's just that it violated the principal of least
surprise. There was an option that needs an argument, and one was
obviously not passed in - that looks like an error to me.

Thanks,

Hunter

Robert Klemme

3/9/2005 10:49:00 AM

0


"Hunter Kelly" <retnuh@gmail.com> schrieb im Newsbeitrag
news:1110361261.109822.170320@o13g2000cwo.googlegroups.com...
> Yah, that's fair enough I suppse (It's what I ended up doing in the
> end), but it seems to me that the default behaviour should be to not
> match it if it looks like another option. For the special case of
> options for another program (or whatever), then put in the special
> matching objects or whatever.

I don't think so. It's your case which is the more restrictive one => you
should specify that you dont't want to accept option like things as
values. I would not want the general case of "any string" to need
explicit mentioning. IMHO this is the most reasonable default.

> I think for me, it's just that it violated the principal of least
> surprise. There was an option that needs an argument, and one was
> obviously not passed in - that looks like an error to me.

This is clearly dependend on the expections: I would be surprised if a
string option value was rejected if I did not specify the string I
expected. :-) To me this means: use any string.

> Thanks,

You're welcome!

Kind regards

robert