In Mason 1 you can declare component arguments and then refer to them as normal lexically scoped variables:
<%args> $address $city $name </%args> Dear <% $name %>: We will come to your house at <% $address %> in the fair city of <% $city> to deliver your prize!
In Mason 2, components are classes rather than subroutines, so we have attributes rather than arguments. When you call a component, you create an instance of the component class and pass attributes to the constructor.
Attributes have several advantages over arguments: you can refer to them in any of the component’s methods (unlike in Mason 1, where arguments have to be awkwardly passed to each method) and you can take advantage of Moose’s powerful attribute declarations.
Here’s how this looks without any special syntax:
<%class> has 'address' => (is => 'ro'); has 'city' => (is => 'ro'); has 'name' => (is => 'ro'); </%class> Dear <% $self->name %>: We will come to your house at <% $self->address %> in the fair city of <% $self->city> to deliver your prize!
Clearly, we’ll need to pour some sugar on this.
Mason 2 will provide an <%attr> section, analagous to Mason 1′s <%args>:
<%attr> a b => 'foo' c => (isa => 'Str', default => 'something') </%attr>
This illustrates the three kinds of <%attr> declarations:
- A name by itself: required attribute.
- A name followed by => and a non-paren: optional attribute with a default.
- A name followed by => a paren: specifies Moose attribute options.
You can mix and match these attributes with standard has declarations. The above is equivalent to:
<%class> has 'a' => (required => 1); has 'b' => (default => 'foo'); has 'c' => (isa => 'Str', default => 'something'); </%class>
All attributes will be read-write by default, via MooseX::HasDefaults::RW. Although read-write attributes are sometimes discouraged, I believe they’re appropriate and convenient for these short-lived component objects that are not generally expected to be accessed outside of their class.
To make the frequent access of attributes more convenient, we resort to some limited source filtering evil and implement Perl 6ish $. notation. Specifically, all occurrances of
within Perl sections will be replaced with
where foo is any valid attribute name ([A-Za-z_]w*).
Note that with read-write lvalue attributes, this could even be used for assignment:
$.foo = 5;
Very convenient for attributes which exist chiefly for sharing data between methods.
The $. substitution feature will be made easy to disable, for those who are against it.
Putting it all together
The first example above with attribute declaration and access sugar:
<%attr> address city name </%attr> Dear <% $.name %>: We will come to your house at <% $.address %> in the fair city of <% $.city> to deliver your prize!