tags:

views:

35

answers:

2

I find my self doing this alot:

optparse = OptionParser.new do |opts|
  options[:directory] = "/tmp/"
  opts.on('-d','--dir DIR', String, 'Directory to put the output in.') do |x|
    raise "No such directory" unless File.directory?(x)
    options[:directory] = x
  end
end

It would be nicer if I could specify Dir or Pathname instead of String. Is there a pattern or my ruby-esque way of doing this?

A: 

If you are looking for a ruby-esque way of doing that, I would recommend to give a try to trollop.

Since version 1.1o you can use the io type which accept a filename, URI, or the strings ‘stdin’ or ’-’.

require 'trollop'
opts = Trollop::options do
  opt :source, "Source file (or URI) to print",
      :type => :io,
      :required => true
end
opts[:source].each { |l| puts "> #{l.chomp}" }

If you need the pathname, then it is not what you are looking for. But if you are looking to read the file, then it is a powerful way to abstract it.

duncan
I didn't know about trollop. Neat! I was looking for optparse specific answers, but I'll look at that in the future. :-)
The Doctor What
+2  A: 

You can configure OptionParser to accept (for instance) a Pathname

require 'optparse'
require 'pathname'

OptionParser.accept(Pathname) do |pn|
  begin
    Pathname.new(pn) if pn
    # code to verify existence
  rescue ArgumentError
    raise OptionParser::InvalidArgument, s
  end
end

Then you can change your code to

opts.on('-d','--dir DIR',Pathname, 'Directory to put the output in.') do |x|
steenslag
Thanks! That not only answers my question but gives a good example of how to extend optparse to accept more things!
The Doctor What