[Catalyst] Re: using Plugin::Singleton and testing

A. Pagaltzis pagaltzis at gmx.de
Fri Nov 17 14:47:18 GMT 2006


* Jonathan Rockway <jon at jrock.us> [2006-11-17 06:45]:
> On Thursday 16 November 2006 20:08, A. Pagaltzis wrote:
> > A singleton is nothing but a global variable, except the
> > identifier comes from the class namespace rather than the
> > variable namespace. Put it in a global variable already.
> 
> Not entirely true.  Try this:
> 
> $global = "Oops, accidentally overwrote the instance with garbage.";
> 
> vs.
> 
> Singleton->get_instance() = "Oops, accidentally overwrote the instance.";
> 
> One will cause an error at some indeterminable time after the
> mistake, the other throws an error immediately, at the line
> where the mistake was made. Which do you prefer?

I prefer to `use Readonly`.

> The point is, a Singleton isn't just a global variable, it's an
> encapsulated piece of data that your program can easily access
> anywhere.

A rose by any other name…

> Compare this code:
> 
> package Foo;
> sub new { my $global = shift; bless {global => $global} => 'Foo' }
> sub Bar { Bar->new($self->{global}) }
> sub something { $self->{global}->something(...) }
> package Bar;
> sub new { my $global = shift; bless { global => $global} => 'Foo' }
> sub Baz { Baz->new($self->{global}) }
> sub another { $self->{global}->something(...) }
> # etc.
> 
> to:
> 
> package Foo;
> sub new { bless {} => 'Foo' }
> sub Bar { Bar->new }
> sub something { Global->instance->something }
> package Bar;
> sub new { bless {} => 'Foo' }
> sub Baz { Baz->new }
> sub another { Global->instance->something }
> # etc.
> 
> In cases where many classes need the same data, a Singleton
> really helps simplify the code.

False dilemma.

    package Foo;
    sub new { bless {} => 'Foo' }
    sub Bar { Bar->new }
    sub something { $::global->something }
    package Bar;
    sub new { bless {} => 'Foo' }
    sub Baz { Baz->new }
    sub another { $::global->something }

Btw, `->instance` is noise, necessary in Java only because Java
is crippled. (Lack of inheritance for class methods, restrictions
on class data, etc.) In Perl, there’s no reason not to eschew the
`Singleton->instance->foo()` silliness in favour of the simpler
`Singleton->foo()`. If you must make singletons, that is.

> There are always coupling issues to worry about, of course
> (Singletons can be evil if you use them that way), but there
> are some things that you can really only have one of. The log
> file, the file descriptor "2" (STDERR), the database password,
> etc.

So put them in global variables.

I’ve yet to see an argument that shows how singletons are
anything other than globals with Shiny Pattern Paint. As of yet,
I don’t know how it would even be possible to make such an
argument, because as far as I can tell the concepts are entirely
isomorphic.

Regards,
-- 
Aristotle Pagaltzis // <http://plasmasturm.org/>



More information about the Catalyst mailing list