Skip to content

Use Library Files

This code already looks like it’s in a file, so let’s move it into one.

Terminal window
jq -n '"CAD 175.62" |
def parse_amount: capture("(?<currency>\\p{alpha}{3}) (?<value>[^\\p{space}]+)");
parse_amount'

”From File”

This becomes

Terminal window
echo "\"CAD 175.62\"" | jq --from-file parse_amount.jq

with the function definition and expression now in a new file in the current working directory named parse_amount.jq.

Terminal window
# parse_amount.jq
def parse_amount:
capture("(?<currency>\\p{alpha}{3}) (?<value>[^\\p{space}]+)");
parse_amount

The library file consists of function definitions, followed at the end by one and only one “main program”, which is the expression that jq evaluates when you invoke it.

You get to must decide how to organize your expressions into functions and “main program”. This guide isn’t quite that opinionated… not yet. I don’t want to tell you where to draw the line between “function” and “main program”, but rather help you figure out how to put code on each side of the line. You can always extract a function by moving code from the main program (or from another function!) into the new function, using def. Only now, you can do this in an editing environment that feels more familiar to most programmers.

Growing Pains

When I work in a text file, I feel the extra freedom to use vertical whitespace generously. This allows me to clearly separate the various parts of my program. For jq programs, that mostly means a junk drawer full of functions and then one pipeline of expressions to evaluate. This is usually good enough until…

  • I want to use the same function in multiple programs.
  • I notice that I’m using the same word in the names of a handful of functions with the goal of grouping them together, but isolating them from the rest of the file.
  • I notice that rummaging through the junk drawer to find a particular function is taking longer and longer as I go along.
  • I want to write unit tests (!!) for my functions.1

These are signs that I’d rather isolate the function definitions from the main program and “include” or “import” code from one library file into multiple programs. Fortunately, jq provides us a way to do both of those.

Footnotes

  1. You don’t need to find a testing library for jq to write helpful tests. Since JSON documents are plain text, so testing your jq code screams for the Golden Master technique, exemplified by ApprovalTests. It’s enough, however, just to create a directory called golden_masters, put some files in there, and use git diff golden_masters to check your code as you go. If you insist on looking for a library, however, jqunit was at version 0.1.0-rc as of literally 11 days before I drafted this guide.