The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Patterns in Ruby: Singleton Pattern

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Christopher Williams

Posts: 88
Nickname: sgtcoolguy
Registered: Apr, 2006

Christopher Williams is a Ruby, Rails and Java programmer
Patterns in Ruby: Singleton Pattern Posted: Oct 31, 2006 7:32 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Christopher Williams.
Original Post: Patterns in Ruby: Singleton Pattern
Feed Title: Late to the Party
Feed URL: http://cwilliams.textdriven.com/xml/rss20/feed.xml
Feed Description: Ruby. Rails. Stuff.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Christopher Williams
Latest Posts From Late to the Party

Advertisement

The Singleton pattern is the black sheep of the pattern family. It was easy to grasp, developers everywhere applied it liberally, and an inevitable backlash came against its overuse.

I won't make any judgments or reccomendations on when to use it - but I will show you just how easy it is to apply in Ruby.

The literal translation of the pattern is to create a class level instance method and to hide the new method.

    
class Example
  def initialize
    # do something?
  end

  def self.instance
    return @@instance if defined? @@instance
    @@instance = new
  end
  private_class_method  :new
end

puts Example.instance.object_id  #=> 21783380
puts Example.instance.object_id  #=> 21783380

This example gives you the basic idea, but it doesn't cover many cases you'd like to handle, like cloning or duping the singleton. It also doesn't hide the class level allocate method, which means a sneaky coder could still create another instance through some hacking. Lastly, it's not thread safe.

Luckily, Ruby already provides a module for making classes singletons. It's in the standard library, inside 'singleton.rb'. Here's how you use it:

    
require 'singleton'

class Example
  include Singleton
end

This module will do the same thing as my example above but will also handle hiding allocate, overriding the clone and dup methods, and is thread safe. The library file itself contains a bunch of examples of its usage, and those interested should definitely read through it.

One thing to note about these implementations is that the instance method takes no arguments, so none are passed on to the object's constructor. This makes sense because the first time instance is called those will be the arguments used for this global instance. Setters are typically more appropriate for most singletons.

Since singletons are global in nature setters should be at the class level. As an extra bonus here's the implementation of the class level attr_ methods to generate the vanilla getter/setter methods (stolen from Rails).

class Class # :nodoc:
  def cattr_reader(*syms)
    syms.flatten.each do |sym|
      class_eval(<<-EOS, __FILE__, __LINE__)
        unless defined? @@#{sym}
          @@#{sym} = nil
        end

        def self.#{sym}
          @@#{sym}
        end

        def #{sym}
          @@#{sym}
        end
      EOS
    end
  end

  def cattr_writer(*syms)
    syms.flatten.each do |sym|
      class_eval(<<-EOS, __FILE__, __LINE__)
        unless defined? @@#{sym}
          @@#{sym} = nil
        end

        def self.#{sym}=(obj)
          @@#{sym} = obj
        end

        def #{sym}=(obj)
          @@#{sym} = obj
        end
      EOS
    end
  end

  def cattr_accessor(*syms)
    cattr_reader(*syms)
    cattr_writer(*syms)
  end
end

Now we can create a more realistic singleton:

    
require 'singleton'

class JimmyGrimble
  include Singleton
  cattr_reader :boots
  cattr_accessor :football
end

Read: Patterns in Ruby: Singleton Pattern

Topic: Logic programming in Ruby: a tiny prolog interpreter and symbolic computation Previous Topic   Next Topic Topic: Onward Hoe!

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use