Writing Your Application Declaratively

Some History

There have been many shiny new developments in the Perl community of
late. With Catalyst's switch to Moose, a whole new world of
possibilities was introduced and suddenly available to all Catalyst
developers. Another exciting new idea came along with Devel::Declare:
the ability to provide a declarative syntax for things that used to be
more verbose or repetitious, or just simply to provide an API that goes
beyond what the Perl parser itself provides.

One of the neater examples that came with the availability of those
modules is MooseX::Declare, which allows you to write your classes
like this:

While it might look like it, this is not a source filter in the sense
that we all (hopefully) learned to avoid. The module is still parsed by
perl. When for example the class keyword is hit, MooseX::Declare
takes over and parses the special syntax. When the { opening brace is
found, it gives control back to perl. This has the big advantage that
extensions can be safely combined and also be written in Perl itself. In
fact, the class and method keywords are handled by separate parts
of MooseX::Declare.

The final action creates an endpoint chained to the base we
declared above. The actions all automatically receive a $ctx context
variable in addition to the $self that MooseX::Declare already
provides for methods.

The interesting part is the (Int $id) signature for the action. The
number of positional arguments is used to determine the number of
arguments in the public URL. The above chain would run if the resource
/bar/23 is hit, and it will only match if its argument is an
Int.

We assume that Language must be a valid language string (such as
en); PageName must be an identifier in the Perl sense (starts with
a letter or underscore, not a digit); and SequentialID is a positive
integer. Then, you can hit the above controller with the following:

* /en/show/foo

This will load base with a $lang of en and then dispatch to
show_page with a $name of foo.

* /de/show/23

This will first run base like before, but this time with de as
$lang argument and then execute show_item with an $id of 23.

Of course you can use any number of arguments, and for endpoints even
slurpy arguments are possible:

final action show_page (Str @path) as page under base { ... }

Grouping actions by their base

You often have a single action as a base and many actions that chain off
of it. If that is the case for you, you can use under as a keyword to
group the actions together and save yourself the repetition of the
under option:

Declaring other parts of the application

Of course controllers and actions are the most important components for
which you'd want to have a declarative syntax. But they are not all that
CatalystX::Declare provides you with. You can also declare your
application in a shinier syntax:

Methods and attributes

Since CatalystX::Declare is just an extension of MooseX::Declare
you can use its full power to declare methods and attributes as
well. Here is an example of a complete root controller with methods and
attributes:

Conclusion

The real hard work for all this shinyness is done by
MooseX::Declare. Take a look at CatalystX::Declare on CPAN for a
full description of the available syntax, since the above is only a
quick tour. I also casually skipped over the use of method modifiers
that are applied to actions, which adds even more possibilities.