Singleton or full static class

F

Frank Meyer

In other languages I'm using the singleton pattern when I need a
globally accessible object. But in Ruby so much is an object or behaces
like an object (or can be treated as an object) I'm not sure if I should
use the singleton pattern or make all methods to class methods and use
class variables.
What is the best practise in ruby?





Turing.
 
D

dblack

Hi --

In other languages I'm using the singleton pattern when I need a
globally accessible object. But in Ruby so much is an object or behaces
like an object (or can be treated as an object) I'm not sure if I should
use the singleton pattern or make all methods to class methods and use
class variables.
What is the best practise in ruby?

There's no one answer to that (except I tend to frown on class
variables, because they're so unencapsulated and weird :) You can
create a class, or for that matter any other constant, which will be
visible from "below":

C = Object.new
def C.greet
puts "hi"
end

class D
def initialize
C.greet
end
end

D.new # hi

and so on. Or C can be a class or a module. There are lots of
different techniques available; I don't think there's one that's
always better than all the others.


David

--
* Books:
RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
 
G

Gregory Seidman

In other languages I'm using the singleton pattern when I need a
globally accessible object. But in Ruby so much is an object or behaces
like an object (or can be treated as an object) I'm not sure if I should
use the singleton pattern or make all methods to class methods and use
class variables.

The Singleton pattern is usually a design mistake anyway. See
http://www.adrianmccarthy.com/blog/?p=53 for a good explanation. That
said...
What is the best practise in ruby?

...there is a good way of dealing with such things in Ruby. Consider a
situation in which you think you need a singleton. What you really need is
a handle to some object on which you can call a method (arguably you just
need the method, but if there are enough of them then it pollutes the
global namespace, so let's assume you need an object). We'll call the
object foo_handler:

module Kernel
def foo_handler
::Kernel.foo_handler
end
def self.foo_handler
@foo_handler ||= FooHandler.new
end
end

You now have a (lazy-loading) singleton, which is stored in the Kernel
object (i.e. the object representing the Kernel module). Any time you need
access to it, you call foo_handler (in whatever context). Of course, if and
when it should no longer be a singleton you can change the implementation
of the method in Kernel without disrupting the rest of your code.

You can also omit the first method entirely and simply call
::Kernel.foo_handler explicitly, which gives you the same flexibility
without polluting the global namespace at all. Furthermore, using Kernel is
only an example; there is nothing special about a method on the Kernel
object that wouldn't work just as well as a method on some other constant.
After all, constant names are nothing more than a directory service, in the
same way that a filesystem can be thought of as a database.
--Greg
 
R

Robert Klemme

The Singleton pattern is usually a design mistake anyway. See
http://www.adrianmccarthy.com/blog/?p=53 for a good explanation. That
said...

I find that article is not a good source on the usefulness (or
harmfulness for that matter) of the singleton pattern. Using completely
unrelated items like the presence of multiple windows, servers etc. as
argument against the singleton pattern is - to say the least - a bit
strange and far from convincing.

There are numerous cases where you really just need a single instance
(stateless classes like comparators in Java for example). And the
singleton pattern explicitly deals with the fact that at some point in
time there may be multiple instances needed. And the fix can be as easy
as returning a new created instance instead of a constant.

Don't get me wrong, I am not religious about using this pattern. But if
something is discounted I expect at least sound reasoning.
..there is a good way of dealing with such things in Ruby. Consider a
situation in which you think you need a singleton. What you really need is
a handle to some object on which you can call a method (arguably you just
need the method, but if there are enough of them then it pollutes the
global namespace, so let's assume you need an object). We'll call the
object foo_handler:

module Kernel
def foo_handler
::Kernel.foo_handler
end
def self.foo_handler
@foo_handler ||= FooHandler.new
end
end

You now have a (lazy-loading) singleton, which is stored in the Kernel
object (i.e. the object representing the Kernel module). Any time you need
access to it, you call foo_handler (in whatever context). Of course, if and
when it should no longer be a singleton you can change the implementation
of the method in Kernel without disrupting the rest of your code.

You just presented an implementation of the singleton pattern although
you place the accessor in a different class.
You can also omit the first method entirely and simply call
::Kernel.foo_handler explicitly, which gives you the same flexibility
without polluting the global namespace at all. Furthermore, using Kernel is
only an example; there is nothing special about a method on the Kernel
object that wouldn't work just as well as a method on some other constant.
After all, constant names are nothing more than a directory service, in the
same way that a filesystem can be thought of as a database.

I'd still prefer to keep this outside of Kernel if only to not stuff too
much into this module.

Regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,150
Messages
2,570,853
Members
47,393
Latest member
silloma

Latest Threads

Top