Dance, Computer, Dance

by Ray Grasso


Pieces I've written.

Using ctags on modern Javascript

18 April, 2015

I use Vim as my text editor and ctags for source code navigation.

I’ve found ctag’s default javascript tagging to be lacking so I’ve added the following to my ctags config file to handle some of the newer ES6 ES2015 syntax such as classes1.

Note that the listing below contains comments which ctags config files don’t support. You can find the actual file on Github.


// Constants

// A constant: AAA0_123 = { or AAA0_123: {
--regex-js=/[ \t.]([A-Z][A-Z0-9._$]+)[ \t]*[=:][ \t]*([0-9"'\[\{]|null)/\1/n,constant/

// Properties

// .name = {
--regex-js=/\.([A-Za-z0-9._$]+)[ \t]*=[ \t]*\{/\1/o,object/

// "name": {
--regex-js=/['"]*([A-Za-z0-9_$]+)['"]*[ \t]*:[ \t]*\{/\1/o,object/

// parent["name"] = {
--regex-js=/([A-Za-z0-9._$]+)\[["']([A-Za-z0-9_$]+)["']\][ \t]*=[ \t]*\{/\1\.\2/o,object/

// Classes

// name = (function()
--regex-js=/([A-Za-z0-9._$]+)[ \t]*=[ \t]*\(function\(\)/\1/c,class/

// "name": (function()
--regex-js=/['"]*([A-Za-z0-9_$]+)['"]*:[ \t]*\(function\(\)/\1/c,class/

// class ClassName
--regex-js=/class[ \t]+([A-Za-z0-9._$]+)[ \t]*/\1/c,class/

// ClassName = React.createClass
--regex-js=/([A-Za-z$][A-Za-z0-9_$()]+)[ \t]*=[ \t]*[Rr]eact.createClass[ \t]*\(/\1/c,class/

// Capitalised object: Name = whatever({
--regex-js=/([A-Z][A-Za-z0-9_$]+)[ \t]*=[ \t]*[A-Za-z0-9_$]*[ \t]*[{(]/\1/c,class/

// Capitalised object: Name: whatever({
--regex-js=/([A-Z][A-Za-z0-9_$]+)[ \t]*:[ \t]*[A-Za-z0-9_$]*[ \t]*[{(]/\1/c,class/

// Functions

// name = function(
--regex-js=/([A-Za-z$][A-Za-z0-9_$]+)[ \t]*=[ \t]*function[ \t]*\(/\1/f,function/

// Methods

// Class method or function (this matches too many things which I filter out separtely)
// name() {
--regex-js=/(function)*[ \t]*([A-Za-z$_][A-Za-z0-9_$]+)[ \t]*\([^)]*\)[ \t]*\{/\2/f,function/

// "name": function(
--regex-js=/['"]*([A-Za-z$][A-Za-z0-9_$]+)['"]*:[ \t]*function[ \t]*\(/\1/m,method/

// parent["name"] = function(
--regex-js=/([A-Za-z0-9_$]+)\[["']([A-Za-z0-9_$]+)["']\][ \t]*=[ \t]*function[ \t]*\(/\2/m,method/

Some of these matchers are too eager but a lack of negative look behinds in the regex engine ctags uses makes that a pain to avoid. Instead I have a script which executes ctags and then filters obviously useless tags from the tag file afterwards.

#!/usr/bin/env bash

set -e

# ctags doesn't handle negative look behinds so instead this script
# strips false positives out of a tags file.

ctags "$@"


while [[ $# > 1 ]]

case $key in

# Filter out false matches from class method regex
sed -i '' -E '/^(if|switch|function|module\.exports|it|describe)	.+language:js$/d' $FILE

# Filter out false matches from object definition regex
sed -i '' -E '/var[ 	]+[a-zA-Z0-9_$]+[ 	]+=[ 	]+require\(.+language:js$/d' $FILE

I trigger the script from within Vim automatically using a plugin I wrote called tagman.vim.

  1. I found tools such as jsctags didn’t do the job and, as always, I’d prefer a more minimal approach. 

Making chruby and binstubs play nice

11 February, 2015

Like a gentleman I use chruby and Bundler to manage Ruby versions and gems in my projects.

Instead of typing bundle exec to run gem executables within a project, I prefer saving keystrokes and using an executable’s name on its own1. I also want to avoid installing another tool like Gem home.

So off to binstubs land I go. Bundler generates them for you and these days Rails even ships with a few as standard. These stub files live in your project and ensure the right set of gems for your project are loaded when they’re executed.

Security risks aside I could just prepend my path with ./bin: and walk away—except that chruby auto-switching spoils the party. When I enter a project directory with a .ruby-version file, chruby prepends the current Ruby version paths at the beginning of PATH thereby matching before my previously prepended ./bin:.

Chruby recommends using rubygems-bundler but I don’t want to install another gem to get this to work. So I tweaked my zsh setup to use preexec_functions like chruby to patch my PATH. I add my function to preexec_functions after chruby loads so that my code patches the PATH after chruby does its work.

As for security I use the same scheme as Tim Pope. Add a git alias for marking a git repository as trusted and then only add a project’s bin directory to PATH if it is marked as such.

Now I just mark a repo as trusted via git trust, and its local binstubs are automatically added to my path.

Changes in my .zshenv:

# Remove the need for bundle exec ... or ./bin/...
# by adding ./bin to path if the current project is trusted

function set_local_bin_path() {
  # Replace any existing local bin paths with our new one
  export PATH="${1:-""}`echo "$PATH"|sed -e 's,[^:]*\.git/[^:]*bin:,,g'`"

function add_trusted_local_bin_to_path() {
  if [[ -d "$PWD/.git/safe" ]]; then
    # We're in a trusted project directory so update our local bin path
    set_local_bin_path "$PWD/.git/safe/../../bin:"

# Make sure add_trusted_local_bin_to_path runs after chruby so we
# prepend the default chruby gem paths
if [[ -n "$ZSH_VERSION" ]]; then
  if [[ ! "$preexec_functions" == *add_trusted_local_bin_to_path* ]]; then

The git trust alias from my .gitconfig:

  # Mark a repo as trusted
  trust = "!mkdir -p .git/safe"
  1. Even though I’ve aliased bundle exec to be in my shell I still feel like an animal when I have to type it. 

Adding jspm to a Rails app

6 February, 2015

Recent posts from Glen Maddern and Thoughtbot inspired me to try my hand at some ES6.

I put together a toy app using jspm and liked what I saw.

I then noticed that the latest beta release of React.js supports ES6 classes.

This led me to dust off an old side project that uses React.js and add jspm to it. The app is built using rails so I spent a little time working out a way to add jspm to that.

I’ve stayed away from the asset pipeline and placed the libraries and application Javascript managed by jspm in the public folder of the app directly.

I’ve extracted the results and placed them up on Github.

Automating my OS X Setup

31 October, 2014

I have a new laptop for work so I spent the last week automating its setup using Babushka.

Check it out on Github and feel free to ignore the more obsessive parts of the Readme.

Start with a Monolith

21 September, 2014

The Microservices train is leaving the station baby and everyone is getting on board. Lots of folks have written about Microservices and their benefits but a recent project experience has left me more interested in when you should use the approach.

Here are two posts which jibe with some of what I’ve recently felt.

Eric Lindvall of Papertrail:

When you’re starting out, and when you’re small, the speed at which you can make changes and improvements makes all the difference in the world. Having a bunch of separate services with interfaces and contracts just means that you have to make the same change in more places and have to do busywork to share code.

What can you do to reduce the friction required to push out that new feature or fix that bug? How can you reduce the number of steps that it takes to get a change into the hands of your users? Having code in a single repository, using an established web framework like Rails or Django can help a lot in reducing those steps. Don’t be scared of monolithic web apps when you’re small. Being small can be an advantage. Use it.

Adrian Cockcroft ex. Netflix:

I joined Netflix in ‘07 and the architecture then was a monolithic development; a two week Agile sort of train model sprint if you like. And every two weeks the code would be given to QA for a few days and then Operations would try to make it work, and eventually … every two weeks we would do that again; go through that cycle. And that worked fine for small teams and that is the way most people should start off. I mean if you’ve got a hand full of people who are building a monolith, you don’t know what you are doing, you are trying to find your business model, and so it’s the ability to just keep rapidly throwing code at the customer base is really important.

Once you figure out how… Once you’ve got a large number of customers, and assuming that you are building some Web-based, SasS-based kind of service, you start to get a bigger team, you start to need more availability.

Large projects with long-term timelines seem like good candidates for using the Microservices approach1.

On the other hand, new products or services may not be the right situation to immediately dive in with a Microservices approach. It’s likely that the idea itself is being fleshed out and investing anywhere outside of that core goal is ultimately waste. Carving process boundaries throughout your domain in this early turbulent stage is going to slow you down when you inevitably need to move them.

Pushing infrastructure style functionality—such as logging or email delivery—out into services makes sense, but waiting to see how things develop seems worthwhile when it comes to the core domain. Initially focussing on understanding the domain and investing in getting changes out to production as quickly as possible is likely more important then developing loads of cross-process plumbing.

A monolithic application isn’t such a bad place to start. The trick, as always, is to know when to change that plan.

  1. In fact a brown field or system refresh project seems like an ideal situation to test the waters of implementing them.</span> These projects have a runway long enough to justify the investment required to put all of the required communication, deployment, and monitoring ligatures in place. 

Programming Books Worth a Damn 📚

17 September, 2014

Programming well is hard. Here are a few books that have helped me improve that I recommend.

Practical Object-Oriented Design in Ruby by Sandi Metz

Practical Object-Oriented Design in Ruby by Sandi Metz

This contains plenty of great advice even if you don't code in Ruby. It focusses in on the message passing aspect of OO and how to structure your code around that ideal whilst keeping it amenable to change.

Working Effectively with Legacy Code by Michael Feathers

Working Effectively with Legacy Code by Michael Feathers

This is really about all code and is full of strategies to isolate and deal with problematic code in large untested code bases.

Clean Code by Robert C. Martin

Clean Code by Robert C. Martin

A meditation on what makes code “good”. General advice that covers many aspects of code including readability, clarity of intention, and separation of responsibilities.

Effective Javascript by David Herman

Effective Javascript by David Herman

Short, sharp, and to the point advice for writing Javascript. Points out the rough edges in the language and gives you concise advice on how to deal with them.

The Pragmatic Programmer by Andrew Hunt & Dave Thomas

The Pragmatic Programmer by Andrew Hunt & Dave Thomas

A touch dated in areas but the core principles it espouses are still good and will hold true for a while to come.

Release It! by Michael Nygard

Release It! by Michael Nygard

A book focussed on “the last mile” in software. Getting your code out the door and setup in a way that you can monitor and change it. It also provides interesting techniques for dealing with production issues in distributed systems such as cascading failures.

Confident Ruby by Avdi Grimm

Confident Ruby by Avdi Grimm

A look at techniques to improve the readability and style of your code. Tips on elimating conditionals, using null objects, and more.

Practical Vim by Drew Neil

Practical Vim by Drew Neil

I've used Vim for a long time and this book taught me plenty. A must read if you use Vim as your editor.

The Little Schemer by Friedman & Felleisen

The Little Schemer by Friedman & Felleisen

A great way to learn recursion and some Lisp.