Showing only posts with label trollop. See the RSS for this label, or see all posts.

I’ve release Trollop 2.0. This is the first Trollop release in about two years!

Trollop is pretty stable and I don’t care to tweak it too much, but there was one behavior that has always irked me: how boolean parameters (aka flags) are handled. In pre-2.0, not specifying a flag on the commandline would result in the option being set to its default value; specifying it on the commandline would result in the option being set to the opposite of its default value. This was weird for options with a default of true:

  opt :magic, "Use magic", default: true
Using --magic with the above configuration would result in a :magic => false value in the options hash, which is a little silly. You could change the description to reflect this, but that looks silly too:
  opt :magic, "Don't use magic", default: true

Fixing this issue required breaking the API. I’ve finally bitten that bullet: in Trollop 2.0, I’ve introduced the GNU-style notion of a --no-x negation form for --x parameters. Now, specifying --x will always set the option :x to true, regardless of its default value. Specifying --no-x will always set the option :x to false, regardless of its default value. The default value only comes into play when neither form is given on the commandline.

E.g.:

 opt :magic, "Use magic", :default => true
Using --magic will result in :magic => true, and --no-magic will result in :magic => false, and not using either will result in :magic => true.

The behavior is exactly the same for flags with a default of false, or, equivalently, flags without a default value:

 opt :science, "Use science"
Using --science will result in :science => true, and --no-science will result in :science => false, and not using either will result in :science => true.

There is one special case behavior: if the option itself starts with a “no_”, then you’ll get the opposite behavior:

 opt :no_muffins, "Don't use muffins", :default => true

Using --muffins will result in :no_muffins => false, and --no-muffins will result in :no_muffins => true, and using neither will result in :no_muffins => true.

Finally, The help screen will explicitly display the --no-x form for flags with a default of true, but otherwise Trollop will accept, but not display, the negative form for all flags.

This will probably require some upgrade code for those of you who were using a flag with :default => true, but I think the end result is a much more consistent behavior.

William Morgan, August 15, 2012.

Most programmers are by now familiar with the difference between the number of bytes in a string and the number of characters. Depending on the string’s encoding, the relationship between these two measures can be either trivially computable or complicated and compute-heavy.

With the advent of Ruby 1.9, the Ruby world at last has this distinction formally encoded at the language level: String#bytesize is the number of bytes in the string, and String#length and String#size the number of characters.

But when you’re writing console applications, there’s a third measure you have to worry about: the width of the string on the display. ASCII characters take up one column when displayed on screen, but super-ASCII characters, such as Chinese, Japanese and Korean characters, can take up multiple columns. This display width is not trivially computable from the byte size of the character.

Finding the display width of a string is critical to any kind of console application that cares about the width of the screen, i.e. is not simply printing stuff and letting the terminal wrap. Personally, I’ve been needing it forever:

  1. Trollop needs it because it tries to format the help screen nicely.
  2. Sup needs it in a million places because it is a full-fledged console application and people use it for reading mail in all sorts of funny languages.

The actual mechanics of how to compute string width make for an interesting lesson in UNIX archaeology, but suffice it to say that I’ve travelled the path for you, with help from Tanaka Akira of pp fame, and I am happy to announce the release of the Ruby console gem.

The console gem currently provides these two methods:

  • Console.display_width: calculates the display width of a string
  • Console.display_slice: returns a substring according to display offset and display width parameters.

There is one horrible caveat outstanding, which is that I haven’t managed to get it to work on Ruby 1.8. Patches to this effect are most welcome, as are, of course, comments and suggestions.

Try it out!.

William Morgan, May 19, 2010.

UPDATE 2010-05-19: 12k downloads. Whoohoo!

I just noticed that Trollop 1.16.2 has over 8,000 downloads. That’s roughly an order of magnitude more than Sup. So, yay. Of course I suspect it’s largely thanks to the fact that it’s now a dependency of Cucumber. But I’ll take what I can get.

After all, it’s only been the best option parser for Ruby for three whole years.

Some people get it:

In my experience, OptionParser has been frustrating to use for several reasons, one of them being the poor documentation — hence your question. William Morgan, the author of Trollop, shows no mercy in his criticism (for example, see http://stackoverflow.com/questions/897630/ and http://trollop.rubyforge.org). I can’t dispute what he says.

And some people are merrily producing horrible alternatives.

William Morgan, May 11, 2010.

Trollop 1.16.2 has been out for a while now, but I realized I (heavens!) haven’t yet blogged about it.

Exciting features include:

  1. Scientific notation is now supported for floating-point arguments, thanks to Will Fitzgerald.
  2. Hoe dependency dropped. Finally.
  3. Some refactoring of the standard exception-handling logic, making it easier to customize Trollop’s behavior. For example, check this out:

opts = Trollop::with_standard_exception_handling p do
  p.parse ARGV
  raise Trollop::HelpNeeded if ARGV.empty? # show help screen
end

This example shows the help screen if there are no arguments. Previous to 1.16, this was difficult to do, since the standard exception-handling was baked into Trollop::options. The help message would automatically be displayed if -h was given, but programmatically invoking it on demand was difficult.

So I’ve refactored the standard exception handling into with_standard_exception_handling, and if you want fine-grained control, instead of calling Trollop::options, you now have the option to call Trollop#parse from within with_standard_exception_handling.

You don’t really need any of this stuff, of course, unless you’re really picky about how your exception-handling works. But hey, that’s why I wrote Trollop in the first place….

William Morgan, May 11, 2010.

I’ve just released Trollop 1.15, which fixes an irritating misfeature pointed out by Rafael Sevilla: when Trollop runs out of characters when it’s generating short option names, e.g. when you have a lot of options, it shouldn’t throw an exception and die. It should just continue peacefully.

Trollop’s reign of domination continues!

William Morgan, September 30, 2009.

I’ve released Trollop 1.13. This is a minor bugfix release. Arguments given with =’s and with spaces in the values are now parsed correctly. (E.g. --name="your mom".)

Get it with a quick gem install trollop.

William Morgan, March 16, 2009.

Trollop 1.11 has been released. This is a minor release with only one new feature: when an option <opt> is actually given on the commandline, a new key <opt>_given is inserted into the return hash (in addition to <opt> being set to the actual argument(s) specified).

This allows you to detect which options were actually specified on the commandline. This is necessary for situations where you want one option to override or somehow influence other options. For example, configure’s --exec-prefix and --bindir flags: if --exec-prefix is specified, you want to override the default value for --bindir, unless that’s also given. If neither are given, you want to use the default values.

This should be a backwards-compatible release, except for namespace issues, if you actually had options called <something>-given.

William Morgan, January 30, 2009.

I released a new version of Trollop with a couple minor but cool updates.

The best part is the new :io argument type, which uses open-uri to handle filenames and URIs on the commandline. So you can do something like this:

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}" }

Also, when trying to detect the terminal size, Trollop now tries to `stty size` before loading curses. This gives better results when running under screen (for some reason curses clears the terminal when initializing under screen).

I’ve also cleaned up the documentation quite a bit, expanding the examples on the main page, fixing up the RDoc comments, and generating the RDoc documentation with a modern RDoc, so that things like constants actually get documented.

If you’re still using OptParse, you should really give Trollop a try. I guarantee you’ll write much fewer lines of argument parsing code, and you’ll get all sorts of nifty features like help page terminal size detection.

William Morgan, October 22, 2008.

Looks like there was a Ruby Inside article featuring Trollop a few weeks ago. Partially as a result of this, I have at least two other people contributing patches. For a project that’s been around for a few years and basically had no one but me use it, that’s a nice change of pace.

I’ve also moved it over from SVN to git (hosted on Gitorious), which probably will help some.

William Morgan, July 30, 2008.

Trollop 1.8.1 is out. This is a minor bugfix release, but 1.8, released a few weeks ago but not really advertised, adds new functionality, so I’m describing that here.

The new functionality is subcommand support, as seen in things like git and svn. This feature is actually trivial to use / implement: you give Trollop a list of stopwords. When it sees one, it stops parsing. The end. That’s all you need.

Here’s how you use it:

  • Call Trollop::options with your global option specs. Pass it the list of subcommands as the stopwords. It will parse ARGV and stop on the subcommand.
  • Parse the next word in ARGV as the subcommand, however you wish. ARGV.shift is the traditional choice.
  • Call Trollop::options again with whatever command-specific options you want.

And that’s it. Simple eh?

It continually amazes me how hard other people make option parsing. I think it’s a holdover from their days of using C or Java. Take a look at synopsis for optparse — it’s a ridiculous amount of work for something simple. Or better yet, look at the synopsis for CmdParse. Having to make a class for each command is a clunky Java-ism. I’m sorry, but it’s true. Subclassing is the one option for specializing code in Java; in Ruby we can be far more sophisticated. Take a look at Ditz’s operator.rb for an example of a subcommand DSL.

William Morgan, June 24, 2008.