Sometimes you just want to dump an ASCII table of data:

| Key |    Value    |      Source      |
| baz | default_baz | defaults         |
| foo | file_foo    | file example.yml |
| bar | env_bar     | environment      |

In the past when I wanted to dump some tabular data to the console or to a log I used Ruport. This works well enough, but Ruport is an awfully heavy dependency for such a simple task.

The other day I ported some data dumping code to use Hirb instead. Hirb is about data formatting and formatting alone, rather than being a full reporting framework, so it’s a much lighter dependency. I had tried to make the switch once before, but been confused by the Hirb API. This time at Dan Mayer‘s suggestion I used the Churn gem as an example, and got it working in a few minutes.

There’s already plenty of Hirb documentation on Tagaholic’s site, but most of it seems aimed at more advanced use cases. If all you want to do is format an Array of arbitrary objects as a table, here’s how to do it:

    :fields => [:key, :value, :source],
    :headers => {
      :key    => "Key",
      :value  => "Value",
      :source => "Source"
    :description => false) + "n"

(Example adapted from DACS.)

The :fields key tells Hirb which methods to use as columns – otherwise you’d just get a single-column table with the string representations of the objects. The :headers key lets you specify nice human-friendly headers for the columns. The setting :description to false tells Hirb not to print a line below the table with the total number of rows.

Published by Avdi Grimm


  1. Nice writeup! Fyi, you could use a :header_filter=>:capitalize instead of :headers to transform the headers. The :header_filter option can be a String instance method or a proc.

    The bit about :fields default behavior isn't quite right. If the array of objects are objects from a database table of any eleven major database gems, your :fields are automatically populated with the table's fields. See…. Also array of arrays or hashes are automatically formatted without :fields. See….

    Sorry to hear the hirb API is confusing. Let me know if you have any advice on improving it. I don't know if I mention in the docs how to use hirb's tables directly like churn and dacs do.

    • I initially tried :header_filter => :capitalize, it didn't work. No idea why.

      I think what I said about :fields is correct in the context I was talking about: “an array of arbitrary objects”. A lot of the Hirb documentation focuses on using and customizing Hirb to auto-detect and format objects based on type. Which is great if you're going to have a repeated need to display those objects and you want them to be handled uniformly every time. And if your array contains only one type of object. The purpose of this article was explaining how I answered the question “what if I have a list of arbitrary non-ORM objects and I just want to quickly dump selected fields as a table?”. Perhaps I missed it, but that's the case I didn't find covered in the docs.

      • Makes more sense in that context. If it makes any difference, :header_filter was introduced in version 0.2.10.

  2. Ah, in that context it makes sense. I’ll add that use case to the docs. If it makes any difference, :header_filter was introduced in hirb version 0.2.10.

  3. Makes more sense in that context. If it makes any difference, :header_filter was introduced in version 0.2.10.


Leave a Reply

Your email address will not be published. Required fields are marked *