1HTML::Mason::SubclassinUgs(e3r)Contributed Perl DocumentHaTtMiLo:n:Mason::Subclassing(3)
2
3
4

NAME

6       HTML::Mason::Subclassing - Documentation on Subclassing Internal Mason
7       classes
8

DESCRIPTION

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

Class::Container

15       A number of modules in Mason are subclasses of "Class::Container".
16       This module was originally part of the Mason core as "HTML::Mason::Con‐
17       tainer", but Ken Williams decided to release it separately on CPAN.
18
19       It was created to encapsulate some common behaviors for Mason objects
20       such as parameter validation and the creation of "contained" objects.
21
22       Basically, any Mason object which takes parameters to its constructor
23       must inherit from this module.  Of course, since all of the classes
24       that you might consider subclassing already inherit from "Class::Con‐
25       tainer", you won't need to inherit from it directly.  However, you may
26       need to use some of its methods.
27
28       So before you go further we highly recommend familiarizing yourself
29       with "Class::Container" and its methods.  Also feel free to look at
30       some of the Mason core modules to see how "Class::Container" is used
31       within Mason itself.
32

SUBCLASSABLE CLASSES

34       The following classes have been designed with subclassing in mind:
35
36       * HTML::Mason::Request
37           This object is your old friend $m.  The request contains informa‐
38           tion about the current request context, and provides methods for
39           calling other components.
40
41       * HTML::Mason::Resolver
42           The resolver's job is to translate a component paths into an actual
43           component.  Mason comes with a single Resolver subclass,
44           "HTML::Mason::Resolver::File", which is used to translate component
45           paths into filesystem paths.
46
47       * HTML::Mason::ComponentSource
48           An object of this class represents a component's source.  These
49           objects are instantiated by the resolver when it finds a component
50           matching a given path.
51
52       * HTML::Mason::Lexer
53           The lexer is responsible for parsing a component.  Creating a new
54           lexer would allow you to change Mason's component syntax.
55
56       * HTML::Mason::Compiler
57           The compiler takes the parsed chunks from the lexer and gives them
58           meaning.  The default compiler, "HTML::Mason::Compiler::ToObject",
59           turns a Mason component into a Mason "object file", which contains
60           actual Perl code.
61
62       * HTML::Mason::ApacheHandler
63           The ApacheHandler class is the bridge between the mod_perl world
64           and Mason, primarily Mason's Interp class.
65
66           It also provides its own "HTML::Mason::Request" and
67           "HTML::Resolver::File" subclasses which implement some mod_perl
68           specific behaviors and features.
69
70       * HTML::Mason::Interp
71           The Interp is the core of Mason, and is primarily responsible for
72           making all the other objects do their jobs.
73

CONSTRUCTORS

75       If you choose to override the constructor, which is always "new" with
76       Mason objects, that you make sure to call the superclass's constructor
77       and that you use the object returned by it.  A good boilerplate for an
78       overridden constructor looks something like this:
79
80         sub new
81         {
82             my $class = shift;
83
84             my $self = $class->SUPER::new(@_);
85
86             $self->_do_some_init;
87
88             return $self;
89         }
90

Request

92       What to Subclass?
93
94       One important thing to know about this class is that it is actually
95       several classes.  The first, "HTML::Mason::Request", is used when
96       ApacheHandler is not loaded.  The other,
97       "HTML::Mason::Request::ApacheHandler", is loaded by ApacheHandler and
98       used to provide some mod_perl specific features.  Similar, the CGIHan‐
99       dler class provides its own request subclass,
100       "HTML::Mason::Request::CGIHandler".
101
102       It is impossible to know which one of these to subclass at compile
103       time, since it is possible that your subclass will be loaded before
104       either ApacheHandler or CGIHandler.
105
106       To handle this, simply call the "alter_superclass()" method in your
107       constructor, like this:
108
109         sub new
110         {
111             my $class = shift;
112
113             $class->alter_superclass( $HTML::Mason::ApacheHandler::VERSION ?
114                                       'HTML::Mason::Request::ApacheHandler' :
115                                       $HTML::Mason::CGIHandler::VERSION ?
116                                       'HTML::Mason::Request::CGI' :
117                                       'HTML::Mason::Request' );
118
119             my $self = $class->SUPER::new(@_);
120
121             ...
122
123             return $self;
124         }
125
126       It is quite important that you do this as these handler-specific sub‐
127       classes provide important functionality.  The "alter_superclass()"
128       method is implemented in the "HTML::Mason::Request" base class, and
129       will do the right thing even in cases of multiple inheritance.  It also
130       cooperates with "Class::Container" to make sure that it sees changes to
131       the inheritance hierarchy.
132
133       The exec() method
134
135       The "exec" method is called in order to execute a request, and is the
136       method that you are most likely to want to override.
137
138       However, if you do override it we suggest that you make sure to call
139       the parent class's "exec" method to implement the actual component exe‐
140       cution and there is no need for you to re-implement them.
141
142       Since the "exec()" method is scalar/list context-sensitive, your "exec"
143       method will need to preserve that.  Here is a boilerplate:
144
145         sub exec
146         {
147             my $self = shift;
148
149             ... # do something cool
150
151             my @r;
152             if (wantarray)
153             {
154                 @r = $self->SUPER::exec(@_);
155             }
156             else
157             {
158                 $r[0] = $self->SUPER::exec(@_);
159             }
160
161             ... # maybe do some cleanup
162
163             return wantarray ? @r : $r[0];
164         }
165
166       Subrequests
167
168       Your custom request class will also be used to implement subrequests,
169       which are implemented by calling "exec" just like any other method.  If
170       you only want to do certain things in "exec" for the first request, you
171       can simply check the value of "$self->is_subrequest".
172
173       Examples
174
175       See the "MasonX::Request::WithApacheSession" module on CPAN.
176

Resolver and ComponentSource

178       The resolver takes a component path and figures out what component that
179       path corresponds to.
180
181       All resolver classes must implement two methods, "get_info" and
182       "glob_path".  The first takes a component path and returns a new
183       "HTML::Mason::ComponentSource" object.  This object contains informa‐
184       tion about the component, such as its last modified time and its
185       source.  See the "HTML::Mason::ComponentSource" documentation for more
186       details.
187
188       You may choose to provide your own ComponentSource subclass as well, if
189       your resolver implementation can take advantage of it.
190
191       The "glob_path" method is responsible for translating a component path
192       like /foo/*/bar into a list of component paths that match that glob
193       pattern.
194

Lexer

196       The rationale for providing your own lexer would be to extend or
197       replace Mason's syntax.
198
199       The lexer is called by the compiler via its "lex" method.  The argu‐
200       ments it receives are the component name, source, and the compiler
201       object.  See the Compiler class documentation for details on what meth‐
202       ods the lexer can call.
203

Compiler

205       See the Compiler class documentation for details on what methods a sub‐
206       class of this class needs to provide.
207
208       If you simply want to tweak Mason's existing behavior, you will proba‐
209       bly want to subclass "HTML::Mason::Compiler::ToObject", which is the
210       default Compiler class.  For example, if you wanted to do something
211       like make attributes dynamic, you could override the "_flags_or_attr()"
212       method in ToObject.
213
214       If you want to drastically change the behavior, you can subclass
215       "HTML::Mason::Compiler" instead.  An example of this would be creating
216       a compiler that generates "EmbPerl" or "Apache::ASP" as output.
217

ApacheHandler

219       The methods that you are most likely to want to subclass are documented
220       in the "ApacheHandler class" documentation.
221
222       Providing an ApacheHandler subclass gives you a chance to do your own
223       client parameter parsing, as well as the capability of providing a dif‐
224       ferent way of handling requests.
225

CGIHandler

227       Like the ApacheHandler, you could subclass this module in order to pro‐
228       vide your own argument processing or to step in and provide a different
229       way to handle requests.
230

USING SUBCLASSES

232       When using your custom subclasses, we recommend that you take advantage
233       of Mason's ability to construct subclassed object on the fly.
234
235       For example, if you're subclassed the Interp object, you can still let
236       the ApacheHandler object create the Interp object for you, as long as
237       you give it the appropriate interp_class parameter.  This is important
238       because Mason may internally set up certain defaults for contained
239       objects.  For example, the ApacheHandler, by default, will tell the
240       Interp object to use the "HTML::Mason::Request::ApacheHandler" Request
241       subclass.  If you create an Interp object manually and you want to use
242       that Interp object with ApacheHandler, you'll have to specify the same
243       Request class.
244
245       For example:
246
247         my $interp =
248             My::Interp->new
249                 ( request_class  => 'HTML::Mason::Request::ApacheHandler',
250                   my_new_interp_param => 42,
251                 );
252
253         my $ah = HTML::Mason::ApacheHandler->new( interp => $interp );
254
255       It is far easier to simply do this:
256
257         my $ah =
258             HTML::Mason::ApacheHandler->new
259                 ( interp_class => 'My::Interp',
260                   my_new_interp_param => 42,
261                 );
262
263       Your new parameter, "my_new_interp_param", will still be passed to the
264       "My::Interp" constructor, but this also gives ApacheHandler a chance to
265       set various parameters for the Interp object.  Of course, you can still
266       override these defaults explicitly:
267
268         my $ah =
269             HTML::Mason::ApacheHandler->new
270                 ( interp_class => 'My::Interp',
271                   resolver_class => 'My::Resolver'.
272                   my_new_interp_param => 42,
273                 );
274
275       If you need access to the interp object's methods directly, it will be
276       always be available via "$ah->interp".
277
278
279
280perl v5.8.8                       2007-04-17       HTML::Mason::Subclassing(3)
Impressum