Ok, you have a problem that can be easily remedied by a couple of gems. In my last article, I explained when it's worth choosing a gem. But which one should you choose? Let's contemplate a few of the metrics you can use to make an informed choice.
Is the Gem Well-Written?
You don't want to use the code you don't fully understand yourself, and it's more difficult to understand the bad code. It might sound superficial, but it also tells you something about the authors – whether they pay attention to the details and respect language style guides.
Has It Been Tested Extensively?
You want to use code that's robust and doesn't crumble the second you start playing with it. You want to be sure you'll be able to deploy it without crashing the server. Lack of tests simply doesn't instil that kind of confidence. Unless it's a prototype/hobby project (or a proof of concept) and you absolutely must use this gem, stay away.
What Features Does It Provide?
Do you need all of them? How many features will you actually use? How many of them are just 'might come in handy in the future'? You don't want to add bloat to your project. Sooner or later, it's going to grow complex on its own – avoid adding hidden complexity! Don't fall into the trap of thinking 'I might need it someday'. You most likely won't. Focus on the problem at hand.
Check out Its Github Repo
When was the last change committed? Is it actively maintained? How many hanging issues are there? How many PRs? How long does it usually take to merge a PR? The answers to the questions above are usually a good indication of how stable a gem is. If it's in the infancy stage, the API will change a lot, often introducing breaking changes. You don't want to deal with that. On the other hand, if the last commit dates back to 2010, you probably want to avoid it as well. It's dead, and if you ever need to fix it, you'll be on your own.
What you're looking for is this sweet spot of just enough activity to fix potential flaws (with PRs), but not enough to render using it unmaintainable with the constant API changes.
Is There a Sensible CONTRIBUTING.md?
It's nice to be able to contribute to those open-source projects, so make sure the process is sensible and transparent. You don't want to waste your time writing that PR only to find out it won't merge.
What Licence Does It Use?
Make sure you're actually allowed to use it the way you intend to.
Are There Any Disadvantages of Adding a Gem?
You introduce a dependency that you have little or no control over. You essentially trust that somebody (i.e. the gem's maintainer/author) will maintain it. You'd be surprised how often that doesn't really happen. You might end up having to fork it and fix it yourself. And suddenly you have two projects to worry about.
While we've agreed that code quality is important, sometimes the existing solutions are just terribly written, and there's nothing you can do about it. I'm sure you know what it means in the long run – debugging hell and bugs.
Almost every gem you add needs to be loaded at the start of the test suite. This can slow your development cycle considerably.
The DSL might be terrible and make you squirm every time you have to use it.
Are There Any Alternatives?
I'm glad you've asked! Although none of them is as fast as dropping in a gem to Gemfile, they offer different advantages.
So, you have that ginormous mass of code posing as a gem, which provides a lot of fluff you don't really need or care about, but there are some great classes you could totally use. Just take them! Extract the logic (test included!) that you need and adapt it to your environment. Just drop in that module, refactor it if need be, and you're golden. If you don't tell 'em, neither will I.
Now, I realise this isn't always possible, but if the gem is very modular, it can be done. If you see the opportunity and you really need this class/module – don't hesitate!
Maybe the gem is almost what you're looking for, but not quite. There's a module you don't need, or perhaps it needs to support your quirky DSL. If you're fully aware of the responsibilities that await – maintaining the new gem, applying the custom fixes, etc. – fork it and apply the required changes.
Sometimes the existing solutions just won't cut it. Nobody has ever had a similar problem before (highly unlikely), the only gem that solves it looks as if it was written by an unlimited number of chimpanzees equipped with typewriters, or you just hate that friggin' DSL and there are no tests at all.
That's fine. Just write it yourself! No other solution will give you more control over the gem's form and function. The only trade-off is that it will (potentially) take much longer to complete the task you've been assigned, so you'll have to convince your client/managers it's the best solution.
I didn't have to convince you to use gems – you already knew they were awesome! But now, you know how and when to choose them, or whether there's a better alternative.
Hungry for more? Check out the Resources section for 3 lists of the most loved battle-tested gems.