The Accidental Rubyist

invalid byte sequence in UTF-8

Command-line parsing: choice and optiflag

leave a comment »

For some reason, I decided to go for choice, for a tiny time converter (DST) program I had put together. choice has a nice easy way of setting up the options configuration. Easy to remember, no syntax. It has the ability to filter and validate the args. Being a newbie, however I did waste an hour trying to access the param inside the action block using Choice.choices[:param] which was not yet set up. Finally, it dawned on me to use value as in:
action do |value|
as in:

  option :countries do
    long '--countries=[PATTERN]'
    desc 'List all countries, or those matching a pattern'
    action do |value|
      if value == true
        puts TZInfo::Country.all.sort
      else
        puts TZInfo::Country.all.sort.find_all{|item| item.name =~ /#{value}/;  }
      end
      exit
    end
  end

My bad!
Later I got stuck for another hour trying to figure out why my program ran fine when the user entered no timezone (and the default was used), but gave wrong results when he entered it.
Finally I printed ARGV[0] and discovered that choice does not consume ARGV as it parses. I searched the docs, examples etc but there was no mention of how to access unused params.
The command is executed as:


./timeconverter.rb --from="America/New_York" "12:00 PM"

The “–from” is optional and defaults to America/New_York. The “12:00 pm” is not an option. When I used OptionParser, “12:00 PM” would be the only item left on ARGV.

So I thought about shifting ARGV myself. However, I do not know when the user enters “-f ” or “–from=” or the default is invoked. Each would result in “12:00 PM” being in a different slot on ARGV.

A bit rattled by this, I installed Optiflag and played with the samples. Optiflag, too does not shift ARGV, although it does maintain a hash called ARGV.flags and I could remove the flags and values from ARGV so it leaves me with “12:00 PM”. That said, optiflag does print the help very well. If i have 3 mandatory flags, and I enter only one, it only prints out the 2 I have not entered, not the entire options list.

At this stage, I did give yet another visual look at CommandLine and also at GetOpt::Declare — which just blows my mind away, but its not for this lifetime. Perhaps, I’ll just go back to OptionParser or even getoptslong. Commandline parsing should not take me more time that my program itself. I sent a mail to chris of choice.rubyforge.org, waiting for an answer.


# convert Unix newlines (LF) to DOS format (CR/LF)
# – strip newline regardless; re-print with dos EOL
$ cat | ruby -ne ‘BEGIN{$\=”\r\n”}; print $_.chomp’

Advertisements

Written by totalrecall

September 6, 2008 at 9:30 am

Posted in Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: