Design is Refactoring

If Writing is Rewriting, Then Designing is Refactoring

Combining Reek and Overcommit

My team has been using Overcommit for a while. We like how easy it makes it to set up Git commit hooks for the entire team and how easy it is to see what those hooks are.

Recently we decided to add Reek to our Code Quality process. To make it automatic we wanted to run Reek as part of our pre-commit hook. Overcommit already has a default hook for Reek, so making Reek run as part of every commit was super easy. Great!


When committing Reek warned us about smells that we couldn’t change. For example, Reek doesn’t like the default Rails migration syntax for a variety of (good) reasons. But my team isn’t going to change the Rails migration syntax so having Reek warn us about those changes wasn’t useful.

Reek offers many ways to silence these warnings. A recent addition is the exclude_paths configuration option. If you have this in your Reek config file

# Directories below will not be scanned at all
  - db/migrate

Then when you run reek . it won’t tell you about any smelly files in db/migrate. Hooray!


When we ran Reek in our pre-commit hook it kept warning us about files in db/migrate. Why?

Well, what Overcommit does is ask Git for a list of all files that have changed. It then passes each of those files to Reek. So, if a file changes in db/migrate then Reek is run with

reek ./db/migrate/file_that_changed.rb

And Reek’s behavior is to always check a file if given a path to a specific file. Even if the file is in an excluded directory.


After checking if it was cool with the Reek team we submitted a couple of PRs that gave Reek a new option --force-exclusion. We chose the flag name because it’s the same one used by Rubocop. Might as well be consistent. The flag tells Reek to ignore files in an excluded path, even when provided the path to a specific file. This work has been merged into Reek as of version 4.6.0, though you probably want 4.6.1 because of a bug with absolute paths.

For Overcommit to use the new flag you’ll need to update your .overcommit.yml file:

    enabled: true
    flags: ['--single-line', '--no-color', '--force-exclusion']

If you skip that part Reek will not use the new flag and you’ll still get warnings about files in excluded paths.

Now you can easily combine the great work of the Reek and Overcommit teams. Thanks to them for managing such helpful projects!

Refactoring Rust: Primitive Obsession

Fast smelly code is still smelly

Thanks to their small, focused nature problems in Exercism tend to focus on language primitives. Transform this string into a different string, manipulate this number, etc. In the bob exercise students return a string based upon a string input. And in leap students return a boolean based on an integer input.

Students tend to rely on primitives when solving these problems. The example solutions for bob and for leap are indicative. They accept primitive input, use primitives to solve the problem and return primitive results.

This is, in short, primitive obsession. And for people just starting to learn Rust (or any language) primitive obsession is fine. Beginners on the Dreyfus model aren’t yet modeling domains or complex concepts; they are still learning the techniques these problems exercise: syntax, primitives, control flow, etc.

But as students progress through the exercises their skills will evolve and they’ll be able ponder maintainability and design. The question will arise – how do I write good Rust code?

Read More

The Lifetime of Food

A Rusty Analogy using Millennial Stereotypes

Imagine you are out to dinner with some friends. You are all stereotypical Millennials so photographing your meal is expected. For every dish you order each of your friends borrows it, takes a photograph, and then returns it to you.

Well, that’s the plan anyway. Some of your friends are not the most reliable. Will they always return the right dish to you? Will they try to sneak a bite? Human friends are so unreliable. But if your friends were Rust functions you’d have nothing to worry about, thanks to Rust’s rules around borrowing and lifetimes.

Let’s model this dinner party in Rust and see if we can learn a thing or two about borrowing and lifetimes.

Read More

Exercism Shouldn't Make You Cry

The Problem

For the past few months I’ve been contributing to, mostly by expanding the Rust track and helping to standardize the problems across languages. It’s fun, and I think the recent upswing in contributors to Exercism has helped the site significantly.

Case in point: an Exercism student, smarter than myself, did an awesome thing and submitted an issue.

Submitting an issue may not seem like much. “Salty Randos” (as Justin Searls calls them) submit issues all the time, right? But this issue was different. The student was honestly confessing that the Anagram problem that was too hard for beginners. That, like I said, is an awesome thing. Programmers (well, all people, probably) don’t like to say, “This is too hard”. Especially when the thing that’s too hard is a toy programming problem meant to help you learn.

What made this issue all the more pressing for me was that I knew about the problem. I’d just forgotten. I began learning Rust with the leap year problem, which was fun. So I continued on to Anagram.

Where I hit a massive wall.

Read More

Rust via its Core Values

I have a couple of ideas about learning programming languages.

The first is that we do it wrong. I’m sure you’ve experienced this. You try learning a new language and can’t quite see how it all works. Why do I use this syntax here and some other syntax over here? We get frustrated by all the weird bits and go back to a language we know.

I think we do a bad job of learning languages because of how we think about languages. Think back to the last time you discussed a new language. Someone mentioned a new language and then someone else asked about the language’s speed, syntax or web framework of choice.

This is similar to how we talk about cars. Hear about that new Ford Bratwurst? How fast is it? Can I drive it through a lake?

When we talk about languages this way, we make them sound interchangeable. Like cars. I know how to drive a Toyota Hamhock, so I should be able to drive a Ford Bratwurst, no problem. Only the speed and the dashboard vary, right?

But imagine what a PHP car would look like, now imagine how different the Lisp car would be. Moving from one to the other involves a lot more than learning which knob controls the heater.

Read More