Provided by: libhtml-mason-perl_1.60-2_all bug

NAME

       HTML::Mason::Subclassing - Documentation on Subclassing Internal Mason classes

DESCRIPTION

       This is the deep voodoo guide, for folks who want to create their own custom subclasses for parts of
       Mason, such as the Request or Interp objects.

Class::Container

       A number of modules in Mason are subclasses of "Class::Container".  This module was originally part of
       the Mason core as "HTML::Mason::Container", but Ken Williams decided to release it separately on CPAN.

       It was created to encapsulate some common behaviors for Mason objects such as parameter validation and
       the creation of "contained" objects.

       Basically, any Mason object which takes parameters to its constructor must inherit from this module.  Of
       course, since all of the classes that you might consider subclassing already inherit from
       "Class::Container", you won't need to inherit from it directly.  However, you may need to use some of its
       methods.

       So before you go further we highly recommend familiarizing yourself with "Class::Container" and its
       methods.  Also feel free to look at some of the Mason core modules to see how "Class::Container" is used
       within Mason itself.

SUBCLASSABLE CLASSES

       The following classes have been designed with subclassing in mind:

       •   HTML::Mason::Request

           This  object  is  your  old  friend  $m.   The request contains information about the current request
           context, and provides methods for calling other components.

       •   HTML::Mason::Resolver

           The resolver's job is to translate a component paths into an actual component.  Mason  comes  with  a
           single  Resolver  subclass, "HTML::Mason::Resolver::File", which is used to translate component paths
           into filesystem paths.

       •   HTML::Mason::ComponentSource

           An object of this class represents a component's source.   These  objects  are  instantiated  by  the
           resolver when it finds a component matching a given path.

       •   HTML::Mason::Lexer

           The  lexer  is  responsible  for parsing a component.  Creating a new lexer would allow you to change
           Mason's component syntax.

       •   HTML::Mason::Compiler

           The compiler takes the parsed chunks from the lexer and gives them meaning.   The  default  compiler,
           "HTML::Mason::Compiler::ToObject", turns a Mason component into a Mason "object file", which contains
           actual Perl code.

       •   HTML::Mason::ApacheHandler

           The  ApacheHandler class is the bridge between the mod_perl world and Mason, primarily Mason's Interp
           class.

           It also provides its own "HTML::Mason::Request" and "HTML::Resolver::File" subclasses which implement
           some mod_perl specific behaviors and features.

       •   HTML::Mason::Interp

           The Interp is the core of Mason, and is primarily responsible for making all  the  other  objects  do
           their jobs.

CONSTRUCTORS

       If  you  choose to override the constructor, which is always "new" with Mason objects, that you make sure
       to call the superclass's constructor and that you use the object returned by it.  A good boilerplate  for
       an overridden constructor looks something like this:

         sub new
         {
             my $class = shift;

             my $self = $class->SUPER::new(@_);

             $self->_do_some_init;

             return $self;
         }

Request

   What to Subclass?
       One  important  thing  to  know  about  this  class  is  that it is actually several classes.  The first,
       "HTML::Mason::Request",    is    used    when    ApacheHandler    is    not    loaded.     The     other,
       "HTML::Mason::Request::ApacheHandler",  is  loaded  by  ApacheHandler  and  used to provide some mod_perl
       specific   features.    Similar,   the   CGIHandler   class   provides   its   own   request    subclass,
       "HTML::Mason::Request::CGIHandler".

       It  is  impossible to know which one of these to subclass at compile time, since it is possible that your
       subclass will be loaded before either ApacheHandler or CGIHandler.

       To handle this, simply call the alter_superclass() method in your constructor, like this:

         sub new
         {
             my $class = shift;

             $class->alter_superclass( $HTML::Mason::ApacheHandler::VERSION ?
                                       'HTML::Mason::Request::ApacheHandler' :
                                       $HTML::Mason::CGIHandler::VERSION ?
                                       'HTML::Mason::Request::CGI' :
                                       'HTML::Mason::Request' );

             my $self = $class->SUPER::new(@_);

             ...

             return $self;
         }

       It is  quite  important  that  you  do  this  as  these  handler-specific  subclasses  provide  important
       functionality.   The  alter_superclass()  method is implemented in the "HTML::Mason::Request" base class,
       and will  do  the  right  thing  even  in  cases  of  multiple  inheritance.   It  also  cooperates  with
       "Class::Container" to make sure that it sees changes to the inheritance hierarchy.

   The exec() method
       The  "exec" method is called in order to execute a request, and is the method that you are most likely to
       want to override.

       However, if you do override it we suggest that you make sure to call the parent class's "exec" method  to
       implement the actual component execution and there is no need for you to re-implement them.

       Since  the exec() method is scalar/list context-sensitive, your "exec" method will need to preserve that.
       Here is a boilerplate:

         sub exec
         {
             my $self = shift;

             ... # do something cool

             my @r;
             if (wantarray)
             {
                 @r = $self->SUPER::exec(@_);
             }
             else
             {
                 $r[0] = $self->SUPER::exec(@_);
             }

             ... # maybe do some cleanup

             return wantarray ? @r : $r[0];
         }

   Subrequests
       Your custom request class will also be used to implement subrequests, which are  implemented  by  calling
       "exec"  just  like  any  other  method.   If  you  only want to do certain things in "exec" for the first
       request, you can simply check the value of "$self->is_subrequest".

   Examples
       See the "MasonX::Request::WithApacheSession" module on CPAN.

Resolver and ComponentSource

       The resolver takes a component path and figures out what component that path corresponds to.

       All resolver classes must implement two methods, "get_info" and "glob_path".  The first takes a component
       path and returns a new "HTML::Mason::ComponentSource" object.  This object contains information about the
       component, such as its last  modified  time  and  its  source.   See  the  "HTML::Mason::ComponentSource"
       documentation for more details.

       You  may choose to provide your own ComponentSource subclass as well, if your resolver implementation can
       take advantage of it.

       The "glob_path" method is responsible for translating a component path like /foo/*/bar  into  a  list  of
       component paths that match that glob pattern.

Lexer

       The rationale for providing your own lexer would be to extend or replace Mason's syntax.

       The  lexer  is  called by the compiler via its "lex" method.  The arguments it receives are the component
       name, source, and the compiler object.  See the Compiler class documentation for details on what  methods
       the lexer can call.

Compiler

       See  the  Compiler  class  documentation  for  details  on what methods a subclass of this class needs to
       provide.

       If  you  simply  want  to  tweak  Mason's  existing  behavior,  you  will  probably  want   to   subclass
       "HTML::Mason::Compiler::ToObject", which is the default Compiler class.  For example, if you wanted to do
       something like make attributes dynamic, you could override the _flags_or_attr() method in ToObject.

       If  you  want  to  drastically change the behavior, you can subclass "HTML::Mason::Compiler" instead.  An
       example of this would be creating a compiler that generates "EmbPerl" or "Apache::ASP" as output.

ApacheHandler

       The methods that you are most likely to want to subclass are  documented  in  the  "ApacheHandler  class"
       documentation.

       Providing  an  ApacheHandler subclass gives you a chance to do your own client parameter parsing, as well
       as the capability of providing a different way of handling requests.

CGIHandler

       Like the ApacheHandler, you could subclass this module in order to provide your own  argument  processing
       or to step in and provide a different way to handle requests.

USING SUBCLASSES

       When  using  your custom subclasses, we recommend that you take advantage of Mason's ability to construct
       subclassed object on the fly.

       For example, if you're subclassed the Interp object, you can still let the  ApacheHandler  object  create
       the  Interp  object  for  you,  as  long  as you give it the appropriate interp_class parameter.  This is
       important because Mason may internally set up certain defaults for contained objects.  For  example,  the
       ApacheHandler,  by  default, will tell the Interp object to use the "HTML::Mason::Request::ApacheHandler"
       Request subclass.  If you create an Interp object manually and you want to use that  Interp  object  with
       ApacheHandler, you'll have to specify the same Request class.

       For example:

         my $interp =
             My::Interp->new
                 ( request_class  => 'HTML::Mason::Request::ApacheHandler',
                   my_new_interp_param => 42,
                 );

         my $ah = HTML::Mason::ApacheHandler->new( interp => $interp );

       It is far easier to simply do this:

         my $ah =
             HTML::Mason::ApacheHandler->new
                 ( interp_class => 'My::Interp',
                   my_new_interp_param => 42,
                 );

       Your new parameter, "my_new_interp_param", will still be passed to the "My::Interp" constructor, but this
       also  gives  ApacheHandler  a chance to set various parameters for the Interp object.  Of course, you can
       still override these defaults explicitly:

         my $ah =
             HTML::Mason::ApacheHandler->new
                 ( interp_class => 'My::Interp',
                   resolver_class => 'My::Resolver'.
                   my_new_interp_param => 42,
                 );

       If you need access to the  interp  object's  methods  directly,  it  will  be  always  be  available  via
       "$ah->interp".

perl v5.38.2                                       2024-03-05                      HTML::Mason::Subclassing(3pm)