This is something I have been putting together for a project and I didn't see anything comparable on CPAN. Looking for comments, suggestions, and any existing modules that may duplicate the functionality. Samples of the current development release available on request.
Thanks. Rob =head1 NAME Class::Singleton::Registry - A class to register and create singleton class instances =head1 SYNOPSIS use Class::Singleton::Registry; my $dbh = Class::Singleton::Registry->getInstance('dbconn'); my $err = Class::Singleton::Registry->lastError('dbconn'); =head1 DESCRIPTION Inspired by brian d foy's article on implementing a singleton in Perl (The Pearl Review) and "Design Patterns, Elements of Reusable Object-Oriented Software" this module implements a singleton registry. Singleton classes are loaded at runtime based on the contents of a registry.ini file which makes it easy to maintain configuration information (i.e. db usernames/passwords) for a given project. Singletons are loaded by the registry via eval(), so only those singleton libraries actually used will be loaded, no matter how many are listed in the registry.ini file. The default registry.ini file will be pulled from your @INC, so you can make singletons global for your installation, or you can set the .ini path via the use line for project or single script use. =head1 EXAMPLES >>>>>>>>>> sample.pl <<<<<<<<<<< #!c:/perl/bin/perl use strict; use FindBin qw/$Bin/; use Class::Singleton::Registry "$Bin/reg.ini"; # specify config file # getInstance(<name>) will cause the name to be looked up in the registry, # if the name exists, the getInstance() method of the registered class will be # called and returned. The lastError() is provided because some modules # like DBI store their error in a global variable, and since the registry is # supposed to be hiding the real class behind the call, you wouldn't normally # know where to get the error from. my $dbh = Class::Singleton::Registry->getInstance('dbconn') or die Class::Singleton::Registry->lastError('dbconn'); # After retrieving the object, use it like normal. print "COUNT: ", $dbh->selectrow_array("Select Count(*) From Regions"), "\n"; # This is not really needed, and shouldn't be done in most cases. The point of # the singleton is that the object is to be shared, so disconnecting at the wrong # time will only cause problems. The singleton DBI will be created so that it # will close the connection in the DESTROY method, so the explicit disconnect # shouldn't be necessary. $dbh->disconnect; >>>>>>>>>> END <<<<<<<<<<< >>>>>>>>>>> reg.ini <<<<<<<<<<<< [dbconn] CLASS=Class::Singleton::Registry::DBI CONNSTR=dbi:mysql:database=lotemaps;host=localhost USER= PASS= >>>>>>>>>> END <<<<<<<<<<< =head1 NOTES =item Registry Registry entries must contain a [section] head which will be the name entered into the registry, a CLASS value which is the module to load for that name, and any other values which are required by that module. When a class is loaded by the registry, which is triggered by the first creation of an instance, the init() method of the loaded module will be called, and all params in the .ini will be passed to it as a hash. =item Memoization All classes loaded by the registry may optionally allow multiple instances of an object to be created. For example a singleton DBI would allow a single DBI instance to be shared throughout an application, but what if you wanted two different instances for two different databases? This is accomplished by the registry passing the registered name to the singleton class in the init() and getInstance() calls. Modules that allow multiple instances will probably store the cached objects in a hash with the registered name as the key. =item What's the point? (this should probably have been first) The point is that we want a way to share an object like a DBI connection or an Apache::Session object, but we want to avoid using global variables and multiple instance of the object. A singleton class is created to handle this object management. In a simple case a singleton object will create an object (i.e. db connection) when it is first called and store the object in a lexical variable, and on subsequent calls it will return this already created object. In more complex systems the singleton class may cache multiple instances of an object and return any that aren't actively busy, or perhaps it will cache multiple instances based on parameters (i.e. Apache::DBI). ...The point is once your program uses the singleton class you can enhance the singleton without having to change your code. This solves most of the problem but it doesn't allow you to subclass a singleton object. Take this bit of code for instance: use Singleton::Foobar; $obj = Singleton::Foobar->instance(); What if you decided that you need to subclass Foobar at some later point, and that your code needs to use the subclass? Well you end up needing to change a lot of code. So the point of the registry is to create a layer between the singleton and the calling code so that subclasses can be entered into the system seamlessly without any pain. So what you end up with is the ability to share instances of an object throughout your application. You get the ability to easily subclass to swap out certain classes with others and don't need to change the calling code. On top of all of that you also get the ability to store application and site wide configuration information in a single place to save you maintenance headaches in the future. I dunno, that sounds like a good thing to me which is why I built it.. =item Current/Planned Registry Singletons Class::Singleton::Registry::DBI - A DBI singleton, supports multiple instances based on name (currently in development). Class::Singleton::Registry::Session - A singleton based on Apache::Session, it will support multiple instances. Has not yet been started. Class::Singleton::Registry::AppSession - A singleton based on Apache::Session, it will support multiple instances. Has not yet been started. =item Creating Singletons Creating a singleton that can be used with the registry is very straightforward and simple. It must have an init() method, a getInstance() method, and a lastError() method. The type of object returned, the caching mechanism, and all other details are up to the singleton class author. =head1 AUTHOR Robert Hanson <[EMAIL PROTECTED]>