Chapter 2: Components- P2
This example demonstrates all the syntax possibilities for this block. First of
all, we have argument types and names. The valid types are scalar, array,
and hash, represented by their corresponding Perl sigil ($, @, or %), exactly
as would be expected.
It is possible to give an argument a default value to be used if none is
provided when the component is called. Any argument without a default is
considered a required argument. Calling a component without specifying all
its required arguments will cause a fatal exception to be thrown.
An argument's default can refer to an earlier argument, so this is completely
legal:
<%args>
$x
$y => $x * 2 > 20 ? 50 : 100
</%args>
While this block looks as if it contains Perl, it is important to realize that its
syntax is actually something unique to Mason. Importantly, lines should not
end with a semicolon or comma, and each variable definition must be on a
single line.
It is possible to have comments both after an argument declaration and on
their own line. Comments start with the # character and continue to the end
of the line, just as in Perl. Blank lines are also allowed.
<%filter> blocks
A <%filter> block is called after a component has finished running. It is
given the entire output of the component in the $_ variable, and any changes
to this variable are reflected in the output of the component. For example,
this filter uppercases all of the component's output:
<%filter>
s/(\w+)/\U$1/g
</%filter>
<%once> blocks
This block is executed whenever the component is loaded into memory. It is
executed before any other block (including an <%init> block). Any
variables declared here remain in existence (and in scope) until the
component is flushed from memory or the Perl interpreter running Mason
shuts down, whichever comes first. The <%once> section is useful for
things like creating database handles or instantiating large, resource-
intensive objects.
The universe is this big: <% $size %>
<%once>
my $size = calculate_size_of_universe( );
</%once>
<%cleanup> blocks
The cleanup block is executed right before the component exits and is the
counterpart to the <%init> block. It is useful if you have created resources
-- such as circular references -- that need to be freed. Technically, it is the
same as placing a <%perl> block at the end of a component.
<%init>
my $resource = get_a_resource( );
</%init>
... do something interesting with that resource
<%cleanup>
$resource->dispose;
</%cleanup>
Since cleanup code tends to be put at the end of the component anyway,
<%cleanup> blocks aren't very common. Their chief advantage is that
their name is cleanup .
Cleanup blocks are not executed if the component dies or aborts.
<%text> blocks
The contents of this block are output exactly as they are, without any
parsing. This if useful if you need to write a component containing text
about Mason. For example:
<%text>
Substitution tags look like this: <% $var %>.
</%text>
<%doc> blocks
This block is intended for use by component authors for documentation
purposes. Its contents are completely ignored. In the future Mason may do
something more useful with them.
<%doc>
=head1 My Story
This is the part where I tell you what the
component does. But I'd
rather tell you a story about my childhood. When
I was but a
child, my mother said to me ...
</%doc>
As you can see, there's no reason not to use POD (Perl's Plain Old
Documentation markup language) in these blocks, and you can even run
perldoc on a component file.
<%flags> and <%attr> blocks
These two blocks share the same syntax and are used to declare one or more
key/value pairs. The key can contain only letters, numbers, and the
underscore character ( _ ). The value can be any Perl expression whose
results can fit into a scalar (such as a number, string, reference, or undef ).
As in the <%args> block, the syntax in these blocks looks like Perl, but it is
not. First, you cannot end a line with a comma or semicolon. Second, the
whole key/value pair must be on a single line.
The difference between these two is that the <%flags> block may contain
only official Mason flags, which are used to affect the component's
behavior. Currently, there is only one flag defined, inherit. This is used
to specify the component's parent component. Component inheritance is
discussed in Chapter 3
.
The <%attr> block may contain any keys that you want, as the variables
defined in this block are not used by Mason but may be used in your code.
Its contents are available by calling the object's attr() method and giving
the desired key as the argument. See Chapter 5
for the details.
<%flags>
inherit => '/some/other/component'
</%flags>
<%attr>
color => "I'm so blue"
size => 'mucho grande'
</%attr>
My color: <% $m->base_comp->attr('color') %>
There is one other important difference between flags and attributes: flags
refer to only the current component, whereas attributes are part of Mason's
inheritance scheme, discussed in Chapter 5
.
<%def> and <%method> blocks
These two blocks use a syntax slightly different from any other Mason block
because their contents are, in turn, components. The <%def> block contains
a subcomponent, an embedded component that can be called via the normal
Mason component calling syntax. A <%method> block also contains an
embedded component, but one that may be inherited by a component's
children. <%def> and <%method> blocks require a name in the initial tag.
In the following example, a subcomponent named .make_a_link is
defined:
<%def .make_a_link>
<a href="<% $url %>"><% $text %></a>
<%args>
$path
%query => ( )
$text
</%args>
<%init>
my $url = ...
</%init>
</%def>
The name of a subcomponent or method may contain alphanumerics,
underscores ( _ ), dashes ( - ), or periods ( . ). Customarily, a period is the
first character of subcomponent names, in order to distinguish them from
nonembedded components. Methods generally do not follow this
convention; they have names without leading periods.
The main difference between subcomponents and methods is simply that
subcomponents are visible only within the component in which they are
defined, whereas methods are visible outside of the component and can be
inherited via Mason's component inheritance mechanism. Subcomponents
and methods are covered in Chapter 5
.
<%shared> blocks
This block also contains Perl code. Code in this block is executed once per
request, before the <%init> block, but unlike in an <%init> block, the
variables declared in this block are in scope both in the component's main
body and in any subcomponents or methods it may contain. This is useful
for sharing a common chunk of code between all the parts of a single
component. The uses of this block are discussed in Chapter 5
.
Escaping a Newline
When using Mason, you may find that you want to suppress a newline in
your text. A typical example is this:
<pre>
I am
% if ($height < 5) {
not
% } elsif ( $height < 5.75 ) {
not very
% } elsif ( $height > 6.25 ) {
very
% }
tall
</pre>
This will generate the following output if $height is less than 5:
<pre>
I am
not
tall
</pre>
The newlines in the output are not desirable but are unavoidable because of
the need for the Perl code to exist on separate lines. Mason therefore
provides the ability to get rid of a newline simply by preceding it with a
backslash ( \ ).
If we rewrote the preceding example with escaped newlines, it would look
like this:
<pre>
I am\
% if ($height < 5) {