Don’t make perfect modularity the enemy of a good refactor

I often find myself reviewing pull requests and I will find classes that contain a lot of domain-specific logic that aren’t relevant to the class itself. I’ll point it out and the response is often “I plan to extract this out into a gem, but I just haven’t had a chance/I’ve been busy.”

Extracting the functionality out into a gem would be great, but I’ll be the first to admit that’s the kind of task I’d procrastinate to no end. You have to extract the functionality, get the right directory structure, get a gemspec in place, then you have to host the gem on Rubygems or if you gem is private, Gemfury. Even then, when you make changes to the gem you have to go and do a Bundler update on the apps that use the gem.

Don’t start with that solution, though. Start by extracting the out of place functionality into a new class that just lives inside the /lib directory in the application. In Rails apps, everything in /lib is already included so you can really just extract the code into the new class file and you’re ready to go.

You probably feel like you could do better than that, and that’s a great attitude you have, but by extracting functionality into a new class and out of the unrelated class, you just addressed the biggest concern, and if in the future you find that you really do need a gem (for instance, maybe you’ve got other apps that need the functionality in that class) you’ve already got the class and a unit test file (right? right?) separated out to easily slip into a gem.