GSP
Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Support
Contact Us
Online Help
Handbooks
Domain Status
Man Pages

FAQ
Virtual Servers
Pricing
Billing
Technical

Network
Facilities
Connectivity
Topology Map

Miscellaneous
Server Agreement
Year 2038
Credits
 

USA Flag

 

 

Man Pages
Class::StrongSingleton(3) User Contributed Perl Documentation Class::StrongSingleton(3)

Class::StrongSingleton - A stronger and more secure Singleton base class.

  package My::Singleton::Class;

  use base qw(Class::StrongSingleton);
  
  sub new {
     my ($class, %my_params) = @_;
         # create our object instance
         my $instance = { %my_params };
         bless($instance, $class);
         # and initialize it as a singleton
         $instance->_init_StrongSingleton();
         return $instance;
  }
  
  1;
  
  # later in your code ...
  
  # create the first instance of our class
  my $instance = My::Singleton::Class->new(param => "value");
  
  # try to create a 'new' one again, and
  # you end up with the same instance, not
  # a new one
  my $instance2 = My::Singleton::Class->new(param => "other value");

  # calling 'instance' returns the singleton
  # instance expected
  my $instance3 = My::Singleton::Class->instance();
  
  # although rarely needed, if you have to
  # you can destroy the singleton
  
  # either through the instance
  $instance->DESTROY();
  # or through the class
  My::Singleton::Class->DESTROY();
  
  # of course, this is assuming you 
  # did not override DESTORY yourself
  
  # Also calling 'instance' before calling 'new'
  # will returns a new singleton instance
  my $instance = My::Singleton::Class->instance();

This module is an alternative to Class::Singleton and Class::WeakSingleton, and provides a more secure Singleton class in that it takes steps to prevent the possibility of accidental creation of multiple instances and/or the overwriting of existsing Singleton instances. For a detailed comparison please see the "SEE ALSO" section.

Here is a description of how it all works. First, the user creates the first Singleton instance of the class in the normal way.

  my $obj = My::Singleton::Class->new("variable", "parameter");

This instance is then stored inside a lexically scoped variable within the Class::StrongSingleton package. This prevents the variable from being accessed by anything but methods from the Class::StrongSingleton package. At this point as well, the "new" method to the class is overridden so that it will always return the Singleton instance. This prevents any accidental overwriting of the Singleton instance. This means that any of the follow lines of code all produce the same instance:

  my $instance = $obj->instance();
  my $instance = My::Singleton::Class->instance();
  my $instance = $obj->new();
  my $instance = My::Singleton::Class->new();

Personally, I see this an an improvement over the usual Gang of Four style Singletons which discourages the use of the "new" method entirely. Through this method, a user can be able to use the Singleton class in a normal way, not having to know it's actually a Singleton. This can be handy if your design changes and you no longer need the class as a Singleton.

_init_StrongSingleton
This method is used to initialize the Singleton instance, your class must call this. This is a protected method, meaning it can only be called by a subclass of Class::StrongSingleton, otherwise it will throw an exception. It also must be called as an instance method and not as a class method, which means that your constructor should look something like this:

  sub new {
        my $class = shift;
        my $instance = bless({}, $class);
        $instance->_init_StrongSingleton();
        return $instance;
  }
    

You also may not call "_init_StrongSingleton" once a Singleton instance has been established, if you do, and exception will be thrown. This is an unlikely error, but one that may come up if your class has complex initializers. In general you want the Class::StrongSingleton "_init_StrongSingleton" method to be the last step in your class initialization process. It should be noted, that this module performs just fine in multiple inheritance situations, just be sure the "_init_StrongSingleton" method gets properly called.

It is also important to note that there currently is a restriction on constructor names. Your class constructor must be named "new", if it is not an exception is thrown in this method. This is because we hijack the constructor function to insure that no new instances are created, and need to be able to access it by name. In future versions (if there is request for it) I will put in functionality to be able to specify a specific constructor name.

NOTE: In version 0.01 this method was called "_init", but since that is all too common a name, and could easily be accidentely overridden in a subclass, it has been changed. However to maintain backwards compatability, "_init" has been aliased to "_init_StrongSingleton".

instance
If a Singleton instance already exists for the calling class, this will return that instance. Otherwise it will attempt to call "new" on the class, and pass any arguments it may have been given.
DESTROY
WARNING: As you may have already know, this functionality is a dangerous thing, and something not to be done lightly. Make sure you have a really good reason to do it, otherwise you might want to rethink your usage of Singletons.

That said, I felt it a good idea to include some means of destruction for these Singleton class instances. While more often than not you will want your Singleton to never go out of scope and therefore never need to be destroyed (except maybe during global destruction when the interpreter is exiting), there might be sometimes in a long running system/application that it would be desireable to have the ability to DESTROY (or refresh/reload) the Singleton instance of your class. So for these reasons i have also implemented a destructor for the class (using the built in DESTROY method).

This destructor will clean up/restore all of the changes made by the "_init_StrongSingleton" method, so that you class will be restored back to it's original state. Keep in mind, that perl will never call this DESTROY method itself, since there will always be a reference to the Singleton instance stored internally. So if you want to create a new instance you must call the DESTROY method yourself.

  my $instance1 = $obj->instance();
  $obj->DESTORY()
  my $instance2 = SingletonDerivedObject->new();
    

Now the Singleton instance stored in $instance1 is different than the Singleton instance in $instance2.

None that I am aware of. Of course, if you find a bug, let me know, and I will be sure to fix it. This code is derived from code which has been in production use for over 2 years without incident.

I use Devel::Cover to test the code coverage of my tests, below is the Devel::Cover report on this module test suite.

 ------------------------ ------ ------ ------ ------ ------ ------ ------
 File                       stmt branch   cond    sub    pod   time  total
 ------------------------ ------ ------ ------ ------ ------ ------ ------
 Class/StrongSingleton.pm  100.0  100.0   66.7  100.0  100.0  100.0   97.1
 ------------------------ ------ ------ ------ ------ ------ ------ ------
 Total                     100.0  100.0   66.7  100.0  100.0  100.0   97.1
 ------------------------ ------ ------ ------ ------ ------ ------ ------

This module is an alternative to Class::Singleton and Class::WeakSingleton, and provides a more secure Singleton class in that it takes steps to prevent the possibility of accidental creation of multiple instances and/or the overwriting of existsing Singleton instances.

If you think this module is ridiculous overkill written by a paranoid freak, then by all means, use either Class::Singleton or Class::WeakSingleton, I will not be offended. However, if you think I may not be as crazy as people some think, then here is a list of what I see as valuable additions/changes that this module contributes to the world of perl Singletons.

The actual Singleton instance is not accessable to any other module.
Both Class::Singleton and Class::WeakSingleton store the Singleton instance in a package variable called "_instance" which is easily accessable from anywhere else in your code. I know this is just another case of "don't go there because you were not invited", personally I just don't like the idea that the Singleton is unprotected.

Class::StrongSingleton stores the Singleton instance in a lexically scoped package variable within the Class::StrongSingleton package itself, so short of some crazy low level pad-walking, you cannot get to it.

Classes can have 'normal' constructors.
The original Gang of Four Singleton pattern calls for the method "instance" to be used to call a private or protected constructor. I feel this restriction has more to do with the C++ language than it does with common sense. Both Class::Singleton and Class::WeakSingleton expect you to call "instance", and to implement a private constructor called "_new_instance", which the subclasser is expected to override.

Class::StrongSingleton takes a different approach, to initialize your Singleton, you must call "_init_StrongSingleton" as an instance method on a subclass of Class::StrongSingleton. An "instance" method is provided, but it is not the only constructor, but instead, just an accessor for the Singleton instance. Class::StrongSingleton allows you to use the standard constructor "new" to create your Singleton, and then hijacks the "new" method so that it will only ever return the Singleton instance.

All this may sound complicated (or maybe just stupid), but I do have my reasons. Singletons are a design "trick" to get around global variables, and sometimes can be overused/abused. On occasion, I have found myself refactoring out Singletons, to improve the design and/or efficiency of an application. Using the style of this module where "new" can be used quite normally, it makes it much easier to remove Singletons.

It is very difficult to create duplicate or errant instances of a Singleton.
With both Class::Singleton and Class::WeakSingleton a simple call to "_new_instance" will result in a non-Singleton instance of your Singleton class. Yes, yes, I know,... this is another case of "don't go there because you were not invited".

With Class::StrongSingleton; calling "new" will return the Singleton, calling "instance" will return the Singleton and directly calling "_init_StrongSingleton" will result in an exception. A class must purposfully create a constructor method which bypasses Class::StrongSingleton in order to create a duplicate or errant instance.

Once again, I am clearly a paranoid programmer, and you may be thinking 'Why doesn't this freak just use Java or something???'. But the fact is, I love programming in perl precisiely because I can do silly stuff like this. If you don't like/appreciate/care-for this style/methodology/illness then just don't use it, I really will not be offended at all :)

stevan little, <stevan@iinteractive.com>

Copyright 2004 by Infinity Interactive, Inc.

<http://www.iinteractive.com>

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

2005-02-28 perl v5.32.1

Search for    or go to Top of page |  Section 3 |  Main Index

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with ManDoc.