Chapter 4: APIs- P2
Subrequests
Subrequests are request objects that inherit all their settable properties from
their parent. The main difference between calling a component with a
subrequest versus using a regular component call is that subrequests will
invoke the autohandler and dhandler mechanisms, whereas a regular
component call will execute only the called component. Subrequests are
covered in a more detail in Chapter 5
.
•
make_subrequest(comp => component, args => [ ... ], ...)
This method creates a new subrequest object, which you can then
execute via its exec() method. This gives you a chance to override
the parent object's properties by passing in arguments to this method.
•
subexec(comp, args)
This combines the make_subrequest() method and the
subrequest's exec() method in one step. Any argument list given to
subexec() will become the argument list for the called component.
This doesn't give you a chance to set properties of the request,
however. For that, you'll need to use the full two-step approach of
calling make_subrequest() and then exec() on the returned
object.
•
is_subrequest
This method returns a boolean value indicating whether the given
object is a subrequest.
•
parent_request
Calling this method returns the parent request object for a subrequest.
available only if you chose to use the CGI.pm module to handle
incoming request parameters.
This method will return the CGI.pm object that was used to handle
incoming parameters.
•
redirect(url)
Given a URL, this generates a proper HTTP redirect, which is then
sent immediately to the client. This will not work if any output has
been previously sent, which may be the case if flush_buffer()
has been called or if the request is in autoflush mode.
Getting in Close with Buffers
Underneath the hood of the request object, output is handled via buffer
objects, which by default are of the HTML::Mason::Buffer class.
The request object maintains a buffer stack. Output goes to the top buffer on
the stack, which can then manipulate it and pass it on to the next buffer in
the stack, which can in turn do the same, and so on.
Buffers are also used to implement features like the request's scomp()
method.
So why would you want to play with buffers? Chances are you won't want to
simply add more plain old HTML::Mason::Buffer objects to the stack.
That wouldn't achieve much.
But if you were to create a custom buffer subclass, you might want to
selectively stick one onto the stack. For example, if you made a buffer that
traced the source of all output it received, you might want to put it on the
stack only for certain parts of your site during debugging. Just be sure to
remove any buffers you add, or Mason may get confused and your output
may never get sent.
The other buffer-related methods are potentially useful for introspection and
debugging:
•
These first methods are the ones you most likely want to use:
•
attr(name)
Looks for the specified attribute in the component and its parents,
returning the first value found. If the attribute is not found, this
method throws an exception. Attributes are declared in <%attr>
blocks, as covered in "<%flags> and <%attr> blocks" in Chapter 2
.
•
attr_if_exists(name)
Works just like the attr() method except that it simply returns
undef if the specified attribute does not exist.
Of course, this makes it impossible to distinguish between an attribute
with undef as its value and an attribute that is not found. To make