in rubymine, spring, rspec, rails, rspec3

I love RubyMine - I've said so in a previous post - and I do almost all my work within the IDE.

This includes RSpec, which is delightfully integrated with the editor. Until recently, I had used spork as a persistent test runner - spork would run continuously, and each time I pressed the key combination to run a test, it would be handed off to the long-running spork process in the background.

But this stopped working when I upgraded to RSpec 3. Though some StackOverflow answers suggested fixes, many also suggested migrating to spring, a similar quick-start service that was now part of Rails by default.

OK, I thought. Using the same tools as everyone else is good. Standards are good. Omakase is good. Let's convert to Spring.

Start from zero.

I began by deleting my old .rspec and spec_helper.rb files - the spec_helper was full of Spork and RSpec 2.x configuration - nothing worth keeping.

In the Gemfile I uncommented the gem "spork" line, and also told it to grab the latest RSpec, now 3.2.0.

I ran rails g rspec:install to give me new configuration files.

Then I ran a single spec from the terminal, to prove rspec worked:

$ rspec spec/models/foo_spec.rb
Finished in 0.00871 seconds (files took 3.54 seconds to load)

Enable Spring in RubyMine

I started a fresh copy of RubyMine, and navigated its menus to edit the run configurations:

Run > Edit Configurations > Defaults > Rspec
Use pre-load server: - Spring -

I selected Spring in the pre-load server menu. I also ensured that all my existing Rspec run configurations (the ones it creates automatically for each *_spec.rb file) were gone - I wanted it to create them anew, based on the current settings.

Back to the editor windows, I opened the same spec file I'd just run from the terminal and hit Shift-Control-F10 to run it as a test.

But instead of running the test, it just printed Spring's usage message:

Usage: spring COMMAND [ARGS]

Commands for spring itself:

  binstub         Generate spring based binstubs. Use --all to generate a binstub for all known commands.
  help            Print available commands.
  status          Show current status.
  stop            Stop all spring processes for this project.

Commands for your application:

  rails           Run a rails command. The following sub commands will use spring: console, runner, generate, destroy.
  rake            Runs the rake command

Binstubs, eh? That looks promising...

$ spring binstub --all
* bin/rake: spring inserted
* bin/rails: spring inserted

Running from RubyMine again, still no joy - it prints a usage statement only. To see if it was invoking bin/spring, I added a line to that file - puts "* this is bin/spring", and indeed, that prints, but spring doesn't seem to know how to invoke rspec.

Spring Commands RSpec't

As is the custom of my people, I consulted the google, and the README at provided an answer. Spring doesn't know about RSpec out of the box; a plugin is required. That plugin is the spring-commands-rspec gem, which is a great name that reads perfectly well as an English sentence. (As an aside, it would have been helpful if Spring printed suggestions to install plugins whenever presented with a missing command that matched a known plugin name! That would save newcomers a bit of time).

Adding gem 'spring-commands-rspec' and running Bundler again, Spring binstub now adds "rspec" to the list of commands in its usage statement. That's progress.

While doing this, my RubyMine instance was still open, and without changing anything I just hit the button to run the last test again ([>] the "Play" symbol). Success!

That first run took five seconds or so, but when I pressed the button a second time it was instantaneous - indeed, it successfully ran the test in Spring. I hadn't even generated a binstub yet - RubyMine knew how to invoke "spring rspec" on its own.

spring binstub rspec

Occasionally I run all tests from the command line, not RubyMine, so let's add that to Spring as well:

  spring binstub rspec
  * bin/rspec: generated with spring

The global "rspec" does not invoke this, but if I run bin/rspec directly it works, running all tests super-fast. I can live with having to remember to type "bin/rspec" or "spring rspec"... not that it matters, as I mostly run it in RubyMine anyway.

There Can Be Only One!

After running "spring rspec" from a shell prompt, I pressed the [>] button to re-run a spec in RubyMine:

...active_support/dependencies.rb:274:in `require': cannot load such file -- teamcity/spec/runner/formatter/teamcity/formatter (LoadError)

Teamcity is Rubymine-specific code that gets injected when rspec is invoked from Rubymine. When I ran spring from a terminal, however, this module was missing. As RubyMine expected it to be there when it next tried to communicate with my running Spring process, it failed.

A Spring process started from outside RubyMine will confuse and thwart RubyMine's attempts to use Spring.

To fix it, kill the spare:

$ spring status
28729 spring server | TheTubes | started 7 mins  
28732 spring app    | TheTubes | started 7 mins ago | test mode   
$ spring stop

Then in RubyMine, run your test - Shift-Ctrl-F10 or the [>] button - and it runs happily.

The Lost Spring

(This section is based on my experiences on two Linux machines - Ubuntu 12 & 14 - and may not apply on other systems)

After killing the standalone Spring and working exclusively in RubyMine for some hours, all of a sudden it stopped working:

Testing started at 2:16 PM ...  
[email protected]_tubes/gems/spring-1.3.0/lib/spring/sid.rb:39:in `getpgid': No such process (Errno::ESRCH)
  from [email protected]_tubes/gems/spring-1.3.0/lib/spring/sid.rb:39:in `pgid'

Spring was no longer running - and RubyMine was failing to start up an instance of it as it usually did automatically.

The only way I could get it to work again was to shut down RubyMine completely and start it up again.

Through trial and error, I eventually discovered that a Spring process would die if the terminal where I had started RubyMine went away - and it couldn't start a new one without being connected to a terminal (leading to the getpgid error - apparently Spring was really close to its process group leader, in a Norman Bates kind of way).

I'd always started RubyMine by cd'ing to the project directory in a terminal ("konsole" in KDE) and typing mine . &. After a few seconds, the IDE would appear... and I'd still have use of the terminal window for running other things. Sometimes, though, I'd just close that window, forgetting that there was something special about it: it was home to a backgrounded RubyMine process. Doing this for years, I'd never had a problem, until Spring came along.

Spring does not abide loss of its controlling terminal. Now, when I start RubyMine from a terminal, I no longer place it in the background with "&" - I let it be the foreground process, so it has exclusive use of that konsole window, and then minimize that window so I don't have to think about how sad and lonely that terminal process is.

It's kind of an ugly hack, but it works.

It's Terminals All The Way Down

Writing the previous section got me thinking - not everyone starts GUI programs from the command line. Some people like clicking on menus and icons. Might that actually work better?

The controlling terminal of the KDE Desktop shell is the system console - which of course never goes away. What if I could get that to be the terminal where Spring attaches itself?

RubyMine wasn't in my KDE menu system, because I hadn't installed it through the Ubuntu package manager. So I ran it directly from the desktop shell - Ctrl-F2, then "/usr/local/bin/mine". A splash screen appeared, followed by the project picker. I selected my project and ran a spec - success! Ran it a second time, it was instantaneous, proving it was using Spring. A ps listing showed that the spring process wasn't associated with a terminal, like pts/8, but had only a question mark in the TTY column.

What if I kill the spring process? RubyMine simply started another one.

Very, very good.

I then created a KDE launcher icon, in my always-visible taskbar - selecting "/usr/local/bin/mine" as the executable and "/usr/local/RubyMine/bin/rubymine.png" as the icon. I next launched RubyMine from there, opened my project, ran a spec, and it worked flawlessly.

After shutting down RubyMine, spring is still running. Curiously, I start another RubyMine, run the spec again - and it works, using the Spring server started by the previous RubyMine! Perfect, this is a better solution than I was hoping for.

Spring, Devourer of Keystrokes.

One last flaw remained with my setup: when invoking "rails console" from a terminal, if I then control-Z out of it, my terminal session becomes seriously messed up - when I type a shell command, Spring grabs half my keystrokes and feeds them to the rails process that I wanted to suspend. I can't even type "fg" to get back to the rails process, as those characters also get misdirected. The only way out is to close the terminal and start another.

Apparently this is a known issue that has not yet been fixed. My workaround is to not use spring for the "rails" command - use it only for rake and rspec - and just deal with a few extra seconds every time I type "rails console".

In bin/rails, I comment out the "load spring" line. "rails console" now bypasses spring, and my terminal doesn't go all wonky.

(Yeah, I use Control-Z / Suspend far too much. I'm old, I remember when opening another terminal took more than a few seconds, and still have those habits)

Living with Spring

  • Remember that spring doesn't know about rspec unless you add the gem spring-commands-rspec
  • When running in RubyMine, a teamcity/formatter error means there's a non-RubyMine spring running - kill it.
  • If getpgid gives a fatal error, spring's terminal went away - you have to quit RubyMine and start it up again
  • Starting RubyMine from the desktop - not a terminal! - will work around that error.
  • Don't let "rails console" use spring if you're in the habit of suspending shell processes.

in blog, ghost

My Ghost blog has, thus far, been kind of defaultish.

Default theme, no image uploading, no discussions, no external services... I rolled it out quickly so that I could focus on other things.

This seems like a good time to change it - and in the process, learn about a few more SaaS providers.


The default theme is Casper; the files that comprise it aren't even part of the Ghost distribution, but are instead installed via a git submodule. As I want to make changes to the theme, I'm going to instead find another, install it locally, and push it to Heroku along with the rest of the app.

A free one will do for now. From the marketplace at I selected the Draugur theme - I like the look of it and it has placeholders for Disqus support and links to Twitter, Github, etc.

Installing is a simple matter of cloning the git repo and copying the files into content/themes/Draugur. After deploying, the admin page lets me switch to that theme.

I then edited the files - the links to the author's Twitter, Github and other accounts are hard-coded, so I replaced them with my own.

Google Analytics

Is anyone even reading this? Google Analytics can answer that - and that requires changes to the HTML, which I can now do that I have a locally-installed theme.

The first step is to prove I own the domain. This is done by claiming it at - they generate a site verification code, which is placed either in a static file or in the HTML of the main page. With a dynamic site like this, the latter was easier, so I edited content/themes/Draugur/default.hbs to add the meta name="google-site-verification" tag.

Once that was done, the site became available in They provided me with a snippet of Javascript which I included in that same default.hbs template. After another deployment, I was done, and the code was visible... a day or two later I looked at the analytics console and saw that it worked and was logging traffic.


Disqus seems to be the de facto standard comment system for ghost blogs, so much so that most of the themes mention in the descriptions that they support it.

The fact that it needs no server-side component is also a big win, for my free Heroku plan doesn't allow for large databases.

Creating a forum was easy - taking less than a minute - and I then had "barbarian-engineer" allocated as my forum's short name.

The Draugur theme's README provided the Handlebars snippet needed to enable Disqus, which I then transplanted into partials/comments.hbs:

<section class="comments">  
    <div id="disqus_thread"></div>
    <script type="text/javascript">
        var disqus_shortname = 'yourdisqusshortnamehere';
        (function() {
            var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
            dsq.src = '//' + disqus_shortname + '';
            (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);

I deployed this and it worked on the first try - one of the most painless integrations ever.


I've been getting a nag message in the admin tools for some time now:

Ghost is attempting to use a direct method to send e-mail. It is recommended that you explicitly configure an e-mail service. See for instructions

Sure, why not. Email is used only for password resets, but that's kind of an important feature.

Heroku doesn't have a native mail service; one is instead referred to the add-ons directory, which lists several email providers. I choose SendGrid, as I've heard of them before, and they have a free service plan.

Creating a SendGrid account was quick... but there's a manual verification step, which they say will take a few hours. This is Saturday, so it might be even longer... so maybe tomorrow I'll come back to this.

in personal, study, blog

A few days ago I learned of a Thoughtbot project on Github... a "Today I Learned" repository, in which their employees write short markdown articles about things they've learned recently.

This is, of course, a brilliant idea, and I have stolen it and made it mine.

Thoughtbot's TIL:
and my TIL:

I'll try to add content to that repository a few times a week - more frequently than to the blog, and the posts will be shorter.

And a new domain.

The blog's URL is now, replacing the old I've been thinking about this for a few weeks - and find the new name more exciting.

in rubymine, ruby, tools, editors

*deep breath*

I use an IDE.

There, I said it.

Lots of people in the Ruby community look down on IDEs, and instead extol their carefully-curated library of vim plugins.

I'm not one of them.

I use vim every day - for config files, study notes, quick fixes on a remote server - but I don't prefer it as a primary coding environment.

After all, its user interface was designed before I finished elementary school. We can do better now.

I did most of my work in vim for the six years that I worked in Perl, and was always shelling out or switching windows when I needed to do anything but edit code. When I left Perl for Java and PHP, I did my work in Eclipse and NetBeans, and found it much more enjoyable to have everything in front of me, configured by tool vendors who were constantly striving to make the interface better and the plugins more capable.

For my first two years with Ruby I used Netbeans 6, later 7. Sun (later Oracle) provided a plugin with fairly good Ruby support - it would flag syntax errors, provide rudimentary lookup of methods, and would let me run tests right there in the browser - no control-Z or alt-tab required.

Even after Oracle walked away from Ruby support, a community of volunteers still maintained the plugin, and it was good enough.

But then I began having enough Ruby projects that I needed to maintain separate gemsets for them. Enter RVM, the Ruby Version Manager. And here, Netbeans fell flat... while one could configure multiple Ruby interpreters, there was no apparent way to rename them - in the pick-lists they'd all just show up as the bare version string (ie, "ruby-1.9.3-p374") without any clue as to which project's gemset it was.

The HAML plugin, too, was a bit crufty; unmaintained (it had been two or three years since the last update), it choked on some of the perfectly legal syntax I used - not only would it display an error marker at that location, but it would display an error condition all the way to the end of the file, wavy red lines under all the text and big red flags in the margins.

(By no means am I slagging the volunteers who maintained these plugins in the absence of commercial support! I thank them for providing a tool that served me well for two years.)

These issues, and my lukewarm enthusiasm for Oracle as a company, prompted me to look for an alternative, which I found in JetBrains RubyMine.

RubyMine groks Rubyists.

RubyMine was a joy to use from the very first hour. Rather than being an afterthought, Ruby support - with optimizations for Rails - was at the core of its design. RubyMine's integration with RVM is perfect and effortless - it picked up on my RVM configuration for each project without having to be manually configured. Its method lookups, too, are top-notch - while Netbeans could generally provide autocompletion on methods in the same file or in an ancestor class, RubyMine is superb at guessing at the classes of other objects and autocompleting their method names and parameter lists. Not only does it see the methods and classes in my own project, but it's capable of going into gems - using that superb RVM integration, it knows where to look - and lets me immediately and effortlessly jump to the source of third-party modules.

RubyMine's maintainers also understand the mores of the Ruby and Rails communities - they understand how we work and have anticipated what tools are likely to be used. Touch your Gemfile, and RM will offer to install the new gems for you. Add a file, it'll add it to git. HAML syntax highlighting is accurate and works right away - no third-party plugins to hunt down - and Rspec support is fantastic, with a test runner that lets one interact with an individual test (rather than simply capturing the output of a shell command and presenting it as a big block of text). Want coffeescript? It knows that syntax too.

It groks us.

grok means to understand so thoroughly that the observer becomes a part of the observed—to merge, blend, intermarry, lose identity in group experience. It means almost everything that we mean by religion, philosophy, and science—and it means as little to us (because of our Earthling assumptions) as color means to a blind man. (from Stranger in a Strange Land)

For the first time using a dynamic language, I had the sort of editor support that had made Java tolerable. I ended up paying for RubyMine only about a week into the 30-day evaluation period.

Now, I'm no gushing fanboy - I accept that RubyMine has its faults. Setting up spring was a pain (more on this later), and often it's such a CPU hog that I can hear the fan spinning higher to shed that heat. And, of course, being a GUI application, you really have to run it locally. These are minor quibbles; for daily use, RubyMine is the most effortlessly usable Ruby editor around.

in history, personal

Twenty years ago today - 20 January 1995 - I began my first real tech job (not counting student jobs), as a tech support lackey for a small regional internet service provider, MCSNet.

In 1995 there were only two kinds of access - dialup and business-grade leased-line, and we provided both. The main office on west Belmont street was on the third floor of a small office building (the first floor was a medical clinic); the company occupied two suites with a hallway between. One was the business office; the other, much smaller, was a server room, filled with racks of USR Courier modems and phone equipment and a dozen or so servers - not the sort of server-grade hardware you get these days, but common mini-tower 486 or Pentium I machines, running the BSDI operating system (a variant of Unix that had begun as a university research project and was therefore free). These servers would each support thirty or so simultaneous logged-in users with "telnet" (command prompt) sessions running text-based Usenet (discussion board), email and IRC chat clients.

And there were web servers, but web sites were kind of insignificant then, certainly not as important as Usenet.

My first night there, I was one of three tech support agents manning the phones, answering questions about configuring Windows 3.1 machines for dial-up network access. I didn't run Windows myself (I used OS/2, a much better OS that IBM blundered into obscurity), nor had I ever seen any of the programs I was telling people how to set up - I just "winged it" based on general knowledge and some printed screenshots taped to the wall.

The other two agents working that evening had started only a few weeks before I did. When we left and locked the place up on my first night, the senior tech accidentally pressed the panic buttons on the alarm system while trying to lock up - the buttons that were supposed to send a signal to police that meant "armed robbery in progress, come in force", an optional feature that, I was told, the company had paid extra for. We called the owner at home for advice and were told to stay put and keep our hands in plain sight and make no sudden movements.

The armed response never came, though, and after a half hour or so we left. I walked to the CTA Red Line station at Belmont, took the Red line to the Loop, transferred to the Blue, and was back home at Racine and Taylor about an hour later. In the coming months, I'd become well acquainted with the CTA's after-midnight runs.

About a month or so into the job, I was promoted to sysadmin - the owner had just gotten married to the office manager and they were honeymooning in Hawaii, so I got to be in charge of the network, with no one senior to ask for help (little did I know that that would become the defining theme of my career). I began to carry a pager for the first time, a little Motorola unit that clipped to my belt and displayed only numbers. When things were going haywire I'd get either a "911" or the dreaded "666" signal, and had to come running.

I lasted only about six months in that job. The owner (whose name we refugees made a pact to never speak aloud) was pompous, bombastic, and believed himself to be the only competent person in the company - he would tell you exactly why you were incompetent, loud enough so everyone could hear. Tired of the constant verbal abuse, and having received a job offer to do programming work at consulting rates, I formally resigned by handing a letter to the boss's wife; though I offered to stay on several weeks for a smooth transition, I was forcibly logged out of the servers ten minutes later (my terminal process was kill -9'd), and I was escorted out of the building.

That happened in July 1995, at the start of a record-setting heat wave, in which so many people died from heatstroke the county had to rent refrigerated trucks as a temporary morgue. And I had just given up 24-hour access to an air-conditioned office... when the power failed in my apartment building the following day, I ended up spending half the night on a park bench, too hot to sleep.

One of the other tech support lackeys there my first night was Craig Brozefsky - whom I've now known for exactly twenty years as of today, making him my oldest friend from Chicago. About a month after I left, he quit rather dramatically: while the owner was berating an admin staffer on the other side of the office for some trivial thing, Craig walked up to him and said "You don't talk to people like they are dogs", and was fired a few minutes later for insubordination. He went on to specialize in security, becoming highly respected in his field, and is now an engineering team lead at Cisco.

I moved in with Craig, to a small and shabby Rogers Park apartment with insufficient heating and nonexistent cooling. We worked on a few small consulting projects before both taking jobs with another tiny ISP the next year, this one focused more on business services than dialup. They didn't last long; the company burned through their startup cash very quickly without ever generating enough business to keep afloat. But, the contacts we made at these two forgotten service providers have led to twenty years of working on Internet things.