Burying the Lede

Most of us don’t write very readable shell scripts. There are plenty of things we could do better, but today I want to talk about one in particular — burying the lede.

The term “burying the lede” comes from the field of journalism. Here’s the Wiktionary definition:

To begin a story with details of secondary importance to the reader while postponing more essential points or facts.

Like a good news article, code should tell a story. And the story should start with what’s most important. In the case of code, the most important information is the high-level functionality — a succinct summary of what the program does. In other words, write (and organize) the code top-down, as opposed to bottom-up.

Unfortunately, shell script doesn’t make this easy. Due to the way shell scripts are interpreted, you can’t call a function until after you’ve defined it. This leads to most of us structuring our code like this:

function do_something { ... }
function do_something_else { ... }

do_something
do_something_else

The problem with this is that the function definitions will likely take quite a few lines, and we won’t see what the top-level functionality is until we reach the end of the script.

I’d like to propose a standard way to structure shell scripts to mitigate this issue. (I’m really only talking about shell scripts that have function definitions within them.) I’m sure I’ve seen a few scripts do this, but it’s not very common at all.

My proposal is simple:

function main {
  do_something
  do_something_else
}
function do_something { ... }
function do_something_else { ... }

main

This structure lets us start with the lede. We describe the top-level functionality right away. Only then do we get to the secondary details. The name main makes it pretty clear that it contains the top-level functionality.

I’ve recently started writing my shell code like this, and I’m happy with the results. I’ve also started to use some other programming techniques in my shell scripts to improve readability: better naming, extracting more methods, and moving helper methods into separate files. It feels good to treat shell scripts like real code instead of just some stuff I’ve hacked together.

PS. The WordPress theme I’m currently using (Twenty Eleven) also buries the lede — I can barely even see the title of the blog post on my screen without scrolling. I’m going to have to change that soon.

What’s Your Open Source Resolution?

I’ve been using GNU/Linux since 1994, starting with a Slackware 2.2 CD-ROM I ordered from the back of a magazine. I’ve been heavily involved in my local GNU/Linux community since 1999, and I give frequent presentations at various groups. I’ve made some small contributions to several Open Source projects.

But I don’t feel like I’ve done enough to contribute to the wider community. So this year, I’m going to resolve to step up my contributions, and do more.

Change my role in the LUG

I was lucky enough this past year to find someone interested in helping to run the St. Louis GNU/Linux Users Group (STLLUG). I’ve been running the group so long that I’ve somewhat stagnated. It’s great to find someone who will bring a fresh energy and new ideas. Thanks, Andrew!

Mostly freed from the more general administrative tasks (mostly planning meeting topics and speakers), I’m hoping to find the time to work on a few projects. First, I want to overhaul the web site. It needs a new look, as well as an easier way to update it. I’m planning to implement some sort of CMS — possibly WordPress or Octopress, or at the very least, a git repo to manage updates.

Blog regularly

I installed WordPress a long time ago, but I haven’t published many posts. I’ve got a few drafts in various stages. So this year I’m going to actually get the blog going, and hopefully post about once a week. I’ll be sharing things I learn on the Internet, as well as some of the things I learn from my experiences with various technologies and techniques.

Contribute more significant patches

There are a few items I’ve been meaning to work on and contribute. I’d like to finally get around to them:

  • Make the GNU sort command be able to (easily) sort a list of IP addresses, or semantic version numbers.
  • Add MySQL-style commands to PostgreSQL: SHOW DATABASES; SHOW TABLES; DESCRIBE table. (I’m not sure how welcome these additions might be, but I think they’d make transitioning from MySQL easier for people.)

Publish and maintain several Ruby gems

I’ve been working on a few Ruby gems. I’d like to get them to a state where they’re useful to more people. These include:

  • A way to simplify standard CRUD controller actions
  • A way to declare list views in a manner similar to SimpleForm or Formtastic
  • A way to declare ActiveRecord attributes in models using Virtus
  • A higher-level interface to ROM (Ruby Object Mapper)
  • A similar high-level way to define Perpetuity attributes in models using Virtus
  • My Rails template, making it much easier to start a Rails app

Build some apps

I enjoyed building a quick Rails app during last year’s Rails Rumble, even if it doesn’t turn out to be useful or make any money. I’d like to create a few small apps again this year, either in Rails or Apache Cordova. I’ve got some ideas — we’ll see how if they turn into anything useful or worth selling.

Podcast more often

Last year, I started joining the This Agile Life podcast. I enjoy it. I’m hoping to continue with that, and possibly doing some podcasting about Ruby and Rails.

Present at a conference

I’m going to attempt to give a presentation at a conference. I often give presentations at local groups, but haven’t addressed a larger audience. I’ve got a few ideas rattling around, and will see if I can turn them into presentations worthy of a larger conference.

What’s your Open Source resolution?

Bulk Rename in Bash

Here’s a relatively simple way to rename a bunch of files from the command line. It uses sed within a command substitution to compute the new names from the old names.

In this example, we’re renaming files that start with “ABC” to start with “XYZ” instead:

  for i in ABC*; do mv $i $(echo $i | sed -e s/^ABC/XYZ/); done

You’ll have to use shell globbing (wildcards) in the first part, to determine which files will be the source of the renaming, and regular expressions in the second part to translate the old names into the new names.

It’s a good idea to use echo in place of mv before running this, to see what the results will be, so you don’t make a mistake.

Depending on the situation, you may need to adapt this for your particular needs. For example, if you have too many files to rename, you would need to use xargs. Or sed might not be up for the task of transforming the names that you want. Or you might need to use find to find files within a hierarchy. As with any UNIX idiom, there are hundreds of variations on the theme.