[Templates-cvs] cvs commit: TT3/lib/Template/TT3 Factory.pm

cvs@template-toolkit.org cvs@template-toolkit.org
Thu, 04 Dec 2003 15:48:43 +0000


cvs         03/12/04 15:48:43

  Modified:    lib/Template/TT3 Factory.pm
  Log:
  * updated docs
  
  Revision  Changes    Path
  1.2       +175 -6    TT3/lib/Template/TT3/Factory.pm
  
  Index: Factory.pm
  ===================================================================
  RCS file: /template-toolkit/TT3/lib/Template/TT3/Factory.pm,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Factory.pm	2003/12/04 15:12:31	1.1
  +++ Factory.pm	2003/12/04 15:48:42	1.2
  @@ -16,7 +16,7 @@
   #   modify it under the same terms as Perl itself.
   #
   # REVISION
  -#   $Id: Factory.pm,v 1.1 2003/12/04 15:12:31 abw Exp $
  +#   $Id: Factory.pm,v 1.2 2003/12/04 15:48:42 abw Exp $
   #
   # TODO
   #   * if module entry can be a string or hash table, then module() could
  @@ -35,7 +35,7 @@
   use vars qw( $VERSION $DEBUG $ERROR $WARNING $UTILS $MODULES );
   use base qw( Template::TT3::Base );
   
  -$VERSION = sprintf("%d.%02d", q$Revision: 1.1 $ =~ /(\d+)\.(\d+)/);
  +$VERSION = sprintf("%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/);
   $DEBUG   = 0 unless defined $DEBUG;
   $ERROR   = '';
   $UTILS   = 'Template::TT3::Utils';
  @@ -72,6 +72,7 @@
   
       # set utility class
       $self->{ utils } = $config->{ utils }
  +                    || $config->{ UTILS }
                       || $UTILS;
   
       $self->debug("init() => $self\n") if $DEBUG;
  @@ -208,17 +209,185 @@
   
   =head1 DESCRIPTION
   
  -# TODO
  +This module implements a factory for loading other Template Toolkit
  +modules and instantiating objects of different classes.
  +
  +The factory maintains a hash array which maps simple module names
  +(e.g. C<parser>, C<provider>, C<plugin>) onto the Perl modules that
  +provide a partcular implementation (e.g. C<Template::TT3::Parser>, 
  +C<Template::TT3::Provider>, C<Template::TT3::Plugin>).  
  +
  +There are three ways in which the module map for a factory can be defined.
  +The first is by manually adding entries to the C<$Template::TT3::Factory::MODULES>
  +hash array.
  +
  +    use Template::TT3::Factory;
  +
  +    $Template::TT3::Factory::MODULES->{ foo } = 'My::Foo::Module',
  +
  +    my $factory = Template::TT3::Factory->new();
  +
  +The second is by subclassing the module and providing your own C<$MODULES>
  +package variable.
  +
  +    package My::TT3::Factory;
  +    use base qw( Template::TT3::Factory );
  +    use vars qw( $MODULES );
   
  +    $MODULES = {
  +        foo => 'My::Foo::Module',
  +    };
  +
  +    package main;
  +    my $factory = My::TT3::Factory->new();
  +
  +The third way is to define them using a C<modules> argument passed to the
  +constructor.
  +
  +    my $factory = Template::TT3::Factory->new(
  +        modules => {
  +            foo => 'My::Foo::Module',
  +            bar => 'My::Bar::Module',
  +        },
  +    );
  +
  +In fact, the C<modules> constructor parameter can be used in conjunction
  +with either of the first two approaches.  The constructor will merge the 
  +contents of the hash array referenced by the C<$MODULES> package variable
  +with those provided by the C<modules> parameter.
  +
  +The C<create()> method can then be used to create an object of one of the 
  +classed managed by the factory object.  The first argument denotes the 
  +simple name of the required module.  Any additional arguments are forwarded
  +to the appropriate constructor.
  +
  +    my $foo = $factory->create( foo => 10, 20 )
  +        || die $factory->error();
  +
  +The above example is functionality equivalent to:
  +
  +    use My::Foo::Module;
  +
  +    my $foo = My::Foo::Module->new(10, 20)
  +        || die My::Foo::Module->error();
  +
  +The factory ensures that the correct module is loaded, calls the 
  +C<new()> constructor method passing any additional arguments, and 
  +reports back any error that occurred.
  +
  +In some cases, the name of the module you want loaded is not the same
  +as the class of the object that you want instantiated.  To cater for 
  +this, a factory module entry can be defined as a reference to a hash
  +array.  The C<module> item should give the name of the module to load,
  +the C<class> item, the name of the class from which the object should 
  +be instantiated.
  +
  +    my $factory = Temlate::TT3::Factory->new(
  +        modules => {
  +            foo => {
  +                module => 'My::Foo::Module',
  +                class  => 'My::Foo::Class',
  +            },
  +        },
  +    );
  +
  +When the C<create()> method is called, the C<My::Foo::Module> will be 
  +loaded, but the new method will be called against C<My::Foo::Class>.
  +So our earlier example:
  +
  +    my $foo = $factory->create( foo => 10, 20 )
  +        || die $factory->error();
  +
  +Becomes functionality equivalent to:
  +
  +    use My::Foo::Module;
  +
  +    my $foo = My::Foo::Class->new(10, 20)
  +        || die My::Foo::Class->error();
  +
  +If you don't want the C<create()> method to load any module (for example,
  +if you've already loaded it yourself or defined it inline somewhere),
  +then define the C<class> item to the appropriate value but don't define
  +any value for C<module>.
  +
  +    my $factory = Temlate::TT3::Factory->new(
  +        modules => {
  +            foo => {
  +                class  => 'My::Foo::Class',
  +            },
  +        },
  +    );
  +
   =head1 METHODS
   
  -=head2 method1()
  +=head2 new()
   
  -# TODO
  +This constructor method creates a new Template::TT3::Factory object.
   
  -=head2 method2()
  +    use Template::TT3::Factory;
   
  -# TODO
  +    my $factory = Template::TT3::Factory->new();
  +
  +A list or reference to a hash array of named parameters can be provided.
  +The C<modules> parameter can be used to define an additional set of 
  +modules that the factory object should manage.
  +
  +    my $factory = Template::TT3::Factory->new(
  +        modules => {
  +            foo => 'My::Foo::Module',
  +            bar => 'My::Bar::Module',
  +        },
  +    );
  +
  +=head2 module()
  +
  +This method is used to get and set module entries in the factory object.
  +It can be called with two argument as shown in the next example.  The first
  +argument is a simple name for the module, the second argument is the full
  +name of the Perl module that implements it.
  +
  +    $factory->module( wiz => 'My::Wiz::Module' );
  +
  +Alternately, the module entry can be provided as a reference to a hash 
  +array.
  +
  +    $factory->module( 
  +        wiz => {
  +            module => 'My::Wiz::Module',
  +            class  => 'My::Wiz::Class',
  +        },
  +    );
  +
  +It can also be called with a single argument to return the entry for a 
  +particular module.  The return value is either a string denoting the 
  +module name, or a hash reference, depending on the module entry.
  +
  +    my $module = $factory->module('foo');   # My::Foo::Module
  +
  +    my $module = $factory->module('wiz'); 
  +    print $module->{ module };              # My::Wiz::Module
  +    print $module->{ class  };              # My::Wiz::Class
  +
  +When the method is called with a single argument to retrieve a module,
  +the corresponding Perl module (if one is defined) is itself loaded in 
  +preparation for use.
  +
  +=head2 class($name)
  +
  +This method returns the class for a module entry.  If the entry is defined
  +as a hash reference then the C<class> item is used.  Otherwise the module
  +name is used.
  +
  +=head2 create()
  +
  +This method instantiates an object of a class managed by the factory.
  +
  +    my $foo = $factory->create( foo => 10, 20 )
  +        || die $factory->error();
  +
  +The first argument to the C<create()> method provides the short name
  +for the factory module.  Any additional arguments are forwarded to the
  +constructor method for that module.
   
   =head1 AUTHOR
   
  @@ -226,7 +395,7 @@
   
   =head1 VERSION
   
  -$Revision: 1.1 $
  +$Revision: 1.2 $
   
   =head1 COPYRIGHT