[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Singleton Class or Module Functions?

T. Onoma

10/20/2004 10:17:00 PM

I've come across this seemingly indistinct option too many times now. Which is
better? Why choose one over the other?

module ThisInstance
class << self
def hello
puts "Hello World!"
end
end
end

ThisInstance.ameth

or

class This
include Singleton
def hello
puts "Hello World!"
end
end

This.instance.ameth

Thanks,
T.


9 Answers

dblack

10/21/2004 12:44:00 AM

0

T. Onoma

10/21/2004 1:37:00 AM

0

On Wednesday 20 October 2004 08:44 pm, David A. Black wrote:
| Hi --
|
| On Thu, 21 Oct 2004, trans. (T. Onoma) wrote:
| > I've come across this seemingly indistinct option too many times now.
| > Which is better? Why choose one over the other?
| >
| > module ThisInstance
| > class << self
| > def hello
| > puts "Hello World!"
| > end
| > end
| > end
| >
| > ThisInstance.ameth
| >
| > or
| >
| > class This
| > include Singleton
| > def hello
| > puts "Hello World!"
| > end
| > end
| >
| > This.instance.ameth
|
| (Do you mean 'hello' rather than 'ameth'?)

Yes.

| I'm not sure what you mean. What's the connection between them?

It seems the above two types of constructs can be used interchangeably. They
both have but one "instance". The both have the same access to methods. The
singleton has to be instantiated the first go around, but since that's behind
the scenes, that doesn't really make any difference (or does it?).

T.


dblack

10/21/2004 2:34:00 AM

0

Brian Candler

10/21/2004 8:15:00 AM

0

> It seems the above two types of constructs can be used interchangeably. They
> both have but one "instance". The both have the same access to methods. The
> singleton has to be instantiated the first go around, but since that's
> behind
> the scenes, that doesn't really make any difference (or does it?).

In the first case, the object *is* the module. In the second case, you have
two objects: a Class, and an instance of that Class.

I've never seen the need for or benefit of the second case, because to me a
Class is like a potato printer for making a bunch of objects which share the
same methods. If you're only ever going to produce one instance (and you are
enforcing that with Singleton) then there's little point in having a Class
in the first place.

You might as well just create one object directly:

Foo = Object.new
class <<Foo
def hello
puts "Hello, world!"
end
end
Foo.hello

However, making Foo a Module is convenient because it gives you your own
namespace (e.g. for sticking constants in, or private helper classes). So as
long as the module name itself does not clash with another module, you can
be sure that everything else inside won't clash either.

Writing as a Class may make sense if there's any chance you might want to
create more than one instance in the future.

Regards,

Brian.


Gavin Kistner

10/21/2004 2:05:00 PM

0

On Oct 20, 2004, at 4:16 PM, trans. (T. Onoma) wrote:
> module ThisInstance
> class << self
> def hello
> puts "Hello World!"
> end
> end
> end

Thank you for this; I'm just starting my project, and I have 6
'major-feature' handlers which are all Singleton classes -- namespace
and functional-separation wrappers for a bunch of methods. The above
smells cleaner to me.



Gavin Kistner

10/21/2004 2:48:00 PM

0

On Oct 20, 2004, at 4:16 PM, trans. (T. Onoma) wrote:
> I've come across this seemingly indistinct option too many times now.
> Which is
> better? Why choose one over the other?

Ah, here's a reason:

module Foo
class << self
def initialize
puts "Never called"
end
end
end
f = Foo


class Bar
include Singleton
def initialize
puts "Called the first time"
end
end
b = Bar.instance
c = Bar.instance



Brian Candler

10/21/2004 3:43:00 PM

0

> module Foo
> class << self
> def initialize
> puts "Never called"
> end
> end
> end

module Foo
puts "Called once when module loaded"
end

But maybe you want to defer this until some later point in time. You could
always write

module Foo
def self.setup
return if defined?(@initialized)
@initialized = true
puts "Doing it once"
end
end

Foo.setup
Foo.setup

but that's not thread-safe; if that's a concern then Singleton is going to
be better.

Regards,

Brian.


T. Onoma

10/21/2004 5:47:00 PM

0

On Thursday 21 October 2004 10:04 am, Gavin Kistner wrote:
| On Oct 20, 2004, at 4:16 PM, trans. (T. Onoma) wrote:
| > module ThisInstance
| > class << self
| > def hello
| > puts "Hello World!"
| > end
| > end
| > end
|
| Thank you for this; I'm just starting my project, and I have 6
| 'major-feature' handlers which are all Singleton classes -- namespace
| and functional-separation wrappers for a bunch of methods. The above
| smells cleaner to me.

From the responses (thanks for those BTW!) I gather that using modules in this
way is only good if there is no _state_ involved. As Brian points out there
are thread safety issues otherwise. In other words this is good if it's just
a bag of functions --a `toolbox` if you will.

But David has also pointed out that rather then use the a heavy Singleton
class, the virtual class (also called singleton) is probably better.

a = Object.new
class << a
def hello
puts "Hellow World!
end
end

As long as you don't need to ask a.is_a?(SpecialThing) this is lighter weight
solution. But I'm not sure right off how that plays into the initialization
difference you raise. Have any notions on that?

Likewise Thanks,
T.



Jason Voegele

10/21/2004 5:53:00 PM

0

Brian Candler said:
> Writing as a Class may make sense if there's any chance you might want to
> create more than one instance in the future.

I agree with Brian's assessment, and furthermore IMO Singleton is an
anti-pattern. The number of instances of a given class is an application
level decision, not something that should be hard-wired into the class
itself. If you use Dependency Injection (possibly with the help of a
container like Copland) the need for singletons is drastically reduced,
perhaps eliminated altogether.

See the article linked below for a discussion of how "Inversion of
Control"/"Dependency Injection" can help eliminate Singletons. The
article is about the Spring framework for Java, but the concepts should
map fairly straightforwardly to Ruby and Copland.

http://www.theserverside.com/articles/article.tss?l=Sprin...

--
Jason Voegele
"There is an essential core at the center of each man and woman that
remains unaltered no matter how life's externals may be transformed
or recombined. But it's smaller than we think."
-- Gene Wolfe, The Book of the Long Sun