How I Learned To Love Rubocop
As you may know, I’m a, shall we say, older programmer, and as such I’ve developed very strong, quasi-rational opinions over details like indentation and parenthesis. I even wrote a Ruby Style Guide once. (I think I even still believe nearly all of it). And while, I’m traditionally a live-and-let live kind of guy, woe unto the person who comes into my codebase and starts moving stuff around.
So when a co-worker suggested we add Rubocop to all our projects at Table XI, I was… skeptical. Okay, I was adamant. Rubocop is an automated style guide, which has dozens of different rules that you can have it apply to your code, ranging from indentation consistency, to possible error sources, to constructs that have faster equivalents, to things that are just plain not idiomatic Ruby style. You can do things like add Rubocop to your continuous integration build, so that a bad indentation fails the build just like a missing test would.
Still, one of the things about working with a lot of smart people is that you learn to trust them sometimes, and so I was convinced into trying it out.
Six months later, I’m still using it, and actively adding it to new projects. And I have a few things to say.
One concern you might have about adding Rubocop to new projects is the huge amount of existing style discrepancies you’d need to correct before you get anything useful out of that noise.
Rubocop actually handles this experience very well. You can create a “to-do” file, which lists all your current style discrepancies and effectively blocks excludes Rubocop from checking them.
As a result, it’s very easy to set up Rubocop to ignore existing style problems, but still flag issues as they come up on new code, making the barrier to adoption on an existing code base much lower than it might otherwise be.
If you are me, though, you won’t be satisfied having the Rubocop to-do list hanging around, you’ll want to clean things up. Many of the Rubocop rules can autocorrect rule violations, and in my experience the autocorrects are pretty accurate, (about 98%, I’ve had a couple of cases where the underlying code was so goofy that Rubocop got confused).
And the thing is — and I’m pretty sure this says more about Rubocop than it does about me — is that I find it really soothing to unleash the power of Rubocop autocorrect on a codebase. One command, and all the misaligned indentations, or weird single-quoted strings, or extra spaces around braces, just… go away.
Honestly, I’m smiling just thinking about it. Is that weird?
Review, not Readability
You’ll often see people say that the advantage of using a style guide like Rubocop is that it makes the codebase more readable. My experience suggests that’s kind of true, but kind of not.
Rubocop is enough different from my default Ruby style that I still kind of need to translate it in my head, so its not a perfect way to get more readability (plus, some of the specific style cops can leave existing code in a weird layout).
That said, Rubocop really does improve code review by eliminating an entire class of review comments. So the review doesn’t wind up getting derailed by indentation or spacing or anything that your local Ruby pedant (by which I mean me) might add as a comment to your teams pull request. Rubocop makes it more likely that your code review will actually review code, and not spelling.
I also find that Rubocop makes writing code a little faster. There’s a whole class of small decisions I’d normally make while coding or small typos that I’d go back and correct which I now let go with the idea that Rubocop’s autocorrect will clean the code up before I’m done. So this does keep me from getting bogged down in small details.
Ruby into Python
Ruby took from Perl the idea that there should be more than one way to do most things, though Ruby is nowhere near as aggressive about that mandate as Perl is. The idea, at least for Perl’s design, was that with multiple ways to spell the same feature, a developer would be free to use a way that most clearly meshed with the code around it.
An interesting side effect of Rubocop is that it flattens out a lot of those superficial differences in Ruby (and even some less-superficial ones, as Rubocop has definite preferences about the use of some of Ruby’s standard library). A common comment on the Table XI Slack is that Rubocop is almost like a completely different language than Ruby.
Specifically, I think Rubocop makes Ruby much more like Python than it would otherwise be, by standardizing a lot of indentation and parenthesis and the like. That is, Rubocop/Ruby is still not syntactically like Python, but it’s much closer to Python’s “There should only be one clear way of doing things” design aesthetic that Ruby normally is.
It’s kind of quirky
It’s not perfect. I wish it handled line continuation indents the way I’ve been writing them for 20 years (and which I cribbed from Code Complete), updating it can be a little strange as new rules get added in each release. You’ll definitely want to tweak the rules to make it more palatable.
Overall, though, it’s worth a try.
If you want to get started here’s the rubocop.yml settings file I’m using in the examples for my next book. The only thing in there that might be too aggressive for you is the insistence on 80 character lines, which I’m doing for printout reasons, but which you might not care about.