RubyGuides
Share this post!

How To Use The Singleton Pattern In Ruby (And Why You Should Avoid It)

Have you ever wanted to create a class that can only have one instance?

No?

Me neither.

But that’s exactly what the singleton pattern is.

Some people even call this an anti-pattern!

Let’s have a look at a code example, so you know what it looks like.

Singleton Pattern Code Example

The idea of the singleton pattern is that you want a class with only one instance.

To do this:

  • You make the new method private
  • You define a class method named instance that returns the unique instance for the class

Because this is a popular design pattern, the Ruby standard library comes with a Singleton module you can include in any class.

It looks like this:

Now if you try to create a Shop object with Shop.new you’ll see this:

And if you want to get the one & only Shop object you can use the instance method:

You can tell it’s always the same object because the object_id never changes.

What you need to remember:

This is a simple pattern, it limits object creation to 1 object & you can request that object whenever you want.

Why You Shouldn’t Use This Pattern

The singleton pattern is often an excuse to have some form of global variable & we know global variables are bad because you have no control over them. This makes things harder to test & it can increase coupling.

“The real problem with Singletons is that they give you such a good excuse not to think carefully about the appropriate visibility of an object.” – Kent Beck

Imagine having an object that most of your classes depend on, that’s what the singleton pattern can become. Good luck refactoring that!

Now:

Are there any good uses for this pattern?

Searching on Github turned up some repos using the Singleton pattern in conjunction with the Null object pattern. I guess that makes sense, Rails uses this as part of ActionPack.

Here’s the code:

This ensures there will only be one AllType object.

Video

Summary

You learned about the singleton design pattern, how to implement it in Ruby & why you should avoid it most of the time.

What do you think about this pattern? Have you seen it before? Let me know in the comments 🙂

Thanks for reading!

Leave a Comment: