The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
OptionParser Argument Casting

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Eric Hodel

Posts: 660
Nickname: drbrain
Registered: Mar, 2006

Eric Hodel is a long-time Rubyist and co-founder of Seattle.rb.
OptionParser Argument Casting Posted: Jan 5, 2008 10:12 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Eric Hodel.
Original Post: OptionParser Argument Casting
Feed Title: Segment7
Feed URL: http://blog.segment7.net/articles.rss
Feed Description: Posts about and around Ruby, MetaRuby, ruby2c, ZenTest and work at The Robot Co-op.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Eric Hodel
Latest Posts From Segment7

Advertisement

OptionParser is a command-line argument parsing library for Ruby that provides several really nice features. Using OptionParser tends to be verbose, but it is also very flexible. One of it’s features that I really like is argument casting.

Argument casting allows you to validate a command-line option and convert it from the user-supplied String into whichever object you like. The ri for OptionParser has an example similar to this one for casting a floating-point argument into a Float value:

require 'optparse'

options = {}

opts = OptionParser.new do |opts|
  # Cast 'delay' argument to a Float.
  opts.on("--delay N", Float,
          "Delay N seconds before executing") do |n|
    options[:delay] = n
  end
end

opts.parse! ARGV

p options

The second argument to opts.on, Float, tells OptionParser to cast the option’s value to a Float before passing it to the handler block. When you run this example with a number as the argument, you’ll see the value in options is a Float:

<samp>$ ruby op_test.rb --delay 1
{:delay=>1.0}</samp>

If you pass a value that can’t be cast into a Float an OptionParser::InvalidArgument is raised:

<samp>$ ruby op_test.rb --delay X
[...]/optparse.rb:454:in `parse': invalid argument: --delay X (OptionParser::InvalidArgument)
    [...]
    from [...]/optparse.rb:1353:in `parse!'
    from op_test.rb:13</samp>

You can rescue this and provide an appropriate help message.

At the bottom you’ll find some tables of the various casts that are built-in to OptionParser. If none of those do what you want, writing your own is very easy.

In RubyGems, various arguments are automatically cast to the appropriate objects. For example, when you specify a version with `gem install—version ’= 1.2.3’`, the argument ’= 1.2.3’ is turned into a Gem::Requirement:

OptionParser.accept Gem::Requirement do |value|
  Gem::Requirement.new value
end

Gem::Requirement.new knows how to cast a String and raises an exception if it can’t, so we delegate to it to do the work.

If you only want to have a specially formatted string, you can provide a regular expression instead. The DecimalInteger cast is defined like this:

DecimalInteger = /\A[-+]?\d+(?:_\d+)*/io
accept(DecimalInteger) {|s,| s.to_i if s}

So the pattern referenced by the name is used to validate the argument.

You can also provide a pattern as the second argument. The Float cast is defined like this:

floatpat = %r"\A[-+]?[...]"io
accept(Float, floatpat) {|s,| s.to_f if s}

Notice that for each of these, you still need to turn the string argument into the appropriate object.

OptionParser Built-in Casts

With no extra requires, OptionParser can cast the following arguments for you:

NameRequirementsCast to
Object, NilClassAny string, no conversionString
StringAny non-empty stringString
IntegerBinary (0b), octal (0), hexadecimal (0x), or decimal numberInteger
FloatFloating point numberFloat
NumericGeneric number formatFloat for floats, Integer for integers
DecimalIntegerDecimal integerInteger
OctalIntegerOctal, binary or hexadecimal numberInteger
DecimalNumericDecimal numberInteger or Float
TrueClass+, -, yes, no, true, false, niltrue or false, defaults to true
FalseClass+, -, yes, no, true, false, niltrue or false, defaults to false
ArrayComma-separated listArray of Strings
RegexpRegular expression with optionsRegexp

If you require ‘optparse/date’:

NameRequirementsCast to
DateTimeAnything handled by DateTime.parseDateTime
DateAnything handled by Date.parseDate

If you require ‘optparse/shellwords’:

NameRequirementsCast to
ShellwordsAnything handled by Shellwords.shellwordsArray of Strings

If you require ‘optparse/time’:

NameRequirementsCast to
TimeAnything handled by Time.parseTime

If you require ‘optparse/uri’:

NameRequirementsCast to
URIAnything handled by URI.parseURI

Read: OptionParser Argument Casting

Topic: RubyForge and transparent proxies Previous Topic   Next Topic Topic: 24C3 - Ruby on Rails Security

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use