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?

Yes? No? Maybe?

Well…

That’s exactly what the singleton pattern is.

There isn’t a problem with that.

But some people call this an anti-pattern because it can be used as an excuse for bad design.

Let’s have a look at a code example so you can learn how it works.

Singleton Pattern Code Example

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

Here’s how:

  • 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:

require 'singleton'

class Shop
  include Singleton
end

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

Shop.new
# NoMethodError: private method `new' called for Shop:Class

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

Shop.instance.object_id

# 5659218

Shop.instance.object_id

# 5659218

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:

class AllType < Type
  include Singleton

  def initialize
    super "*/*", :all
  end

  def all?; true; end
  def html?; true; end
end

This is a class that inherits from Type.

When you create an AllType object via the instance method, it will call super & return the object.

Every time you call instance after that you'll get the same object.

In conclusion:

Yes, this pattern can be useful in the right situations, but you don't want to use it without thinking a lot about it.

Video

[responsive_video type='youtube' hide_related='0' hide_logo='0' hide_controls='0' hide_title='0' hide_fullscreen='0' autoplay='0']https://www.youtube.com/watch?v=QDqWQrK_FOg[/responsive_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!