Over the past weekend, a new version of the Catalyst web framework was released. Catalyst 5.8 is a significant step in the development of Catalyst and while it changes a significant portion of Catalyst's internals, it retains backward compatibility with applications built on previous versions of Catalyst. With a framework as complex as Catalyst, this is no small feat. Tomas Doran, a major contributor to the 5.8 update, is with us today to tell us more about this major milestone in Catalyst's development.
For our readers who have only heard of Catalyst before, can you tell us briefly what Catalyst is?
Catalyst is a modern framework for building web applications in perl.
Catalyst takes care of handling requests / responses, and gives you a flexible way to map the url space of your application into method calls, and glue your domain logic, database, templating and any other components together in a flexible way.
It's used in many companies internationally, and has multiple well known production deployments (powering two of the worlds most popular streaming media sites for example).
Catalyst had its 5.8 release over this past weekend, congratulations.
Thanks, it feels really great to have finished the second 90% of the project, and be moving onto the third 90%.
[ editor's note: 5.80002 was released to CPAN on April 21 ]
That's funny. How do you feel about deploying on 5.8 now?
You may be asking the wrong person, I've been running 5.8 in production for months now - ages and ages for some of my home projects, and at work since the _05 development release.
Being serious for a second - I'm quite sure that there are some bugs left, and now that we've 'officially' released, they'll come out of the woodwork in the next few days / weeks as all the people who didn't test any of the development releases upgrade.
I guess there will be [another -ed] release to sweep up bugs some time in the next couple of weeks, and if you're paranoid and/or your applications have no test coverage then I might be tempted to hold off until then.
Actually, I think that if my applications had no test coverage, I'd be too afraid to ever upgrade anything, or ever change the application itself - not having tests is a fairly certain way to make sure that your users will spend quite a lot of time telling you that you should have tests (they don't usually phrase it like that however).
What is the big change between the 5.7 release branch and 5.8?
The big change in this release is ripping out all of the basic class-building modules which Catalyst was originally based on, and replacing them with Moose, without requiring applications to change their code.
What does the switch to Moose do for Catalyst?
It gives the user all the power of Moose in their applications, makes customising the framework in applications and extensions much easier, allows extensions to interoperate better with each other, and allows extensions to change some important core features for the first time.
What kinds of features can you change now that you couldn't before? How does Moose help with that?
The biggest thing which can change which couldn't before is the attribute syntax for controller actions - this is used to declare what methods in the application participate in dispatch, and are potentially routable from a URI.
The reason these can be changed now (when they couldn't before) is that refactoring has decoupled how these attributes are represented from how the actions are built as Catalyst starts. Moose helped with this as it actually has a place for additional metadata about methods which the data could be moved to, rather than the horrible class-data based method generally used with attributes.
Apart from the switch to Moose, are there any new features in 5.8 people should know about?
Roles (also knows as Traits outside the Moose community) are a solution to the issues with multiple inheritance, and a method of code reuse. They basically allow you to compose chunks of additional functionality onto your class.
Rather than have base class(es), and method resolution which falls back if the method isn't defined in your parent class, the functionality is injected _directly_ into your class, as if you had copy and pasted the role definition into the code.
This means that things like conflicting methods (same method name being composed by two roles) can be caught *at compile time*, which is awesome.
Method modifiers 'wrap' methods, allowing you to run code before or after them, or instead wrap around the whole method (and optionally not delegate).
These combine nicely with roles, and if you ensure your methods are small, then generally its possible to overlay and extend your code just by wrapping (or just suffixing/prefixing) existing methods.
Some other new things are:
[% c.uri_for_action('/controller/edit', c.req.captures) %] - very nice way of generating urls to chained actions.
Being able to treat $c->res as a file handle - this was the feature I ran a 5.8 dev release in production for, really useful. :)
I understand it's taken a significant amount of effort to get 5.8 released. How long has the 5.8 branch been under construction?
The first commit was March 10th 2008, so just over a year.
Catalyst has a strong testing culture and a mandate of "don't break backwards compatibility". How much of a challenge was that while preparing Catalyst 5.8 for release?
I deployed my first production Catalyst application some time in 2006, and that application runs unmodified on 5.8.
It was a fairly huge challenge. Replacing the three core technologies (NEXT, Class::Accessor::Fast, Class::Data::Inheritable) which Catalyst was originally built from, whilst keeping backwards compatibility with not only user applications, but the plethora of CPAN extensions which have been written to extend the framework was quite a lot of work.
We smoke tested against a lot of the applications and extensions on CPAN several times, did 7 development releases and spent a lot of effort fixing unusual, but reasonable things found in the wild.
Does 5.8 have any hidden gems people might be interested in?
Catalyst::Test is more flexible and useful in 5.8. It can now test multiple vhosts (useful if your application is presented / skinned differently for different sites), and it is possible to get the request context back, so that you can test the stash/etc. is in the state you expect after a request.
The restarter works much better! It has been taught how to deal with immutable Moose classes, and can also now detect non-trivial cases where you have multiple packages declared in one file.
Catalyst 5.8's Moosification will enable a lot of new functionality. Anything in particular you are looking forward to trying in upcoming releases?
Actually, one of the aims of 5.8 was to enable a lot more flexibility without having to have the functionality in core.
There's more core refactoring to do, of course - but we're now in a position where I hope to see several competing methods of action declaration on the CPAN to replace the ageing attribute syntax; this wouldn't have been possible in a reasonable way previously.
Any final words?
There is obviously loads still to do - from prototyping new features now possible, through to updating documentation and tutorials to reflect native Moose components; anyone interested in knowing more and helping out, please post on the list, or feel free to stop by #catalyst-dev for a natter. I promise to find something you're able to volunteer for ;-)
In addition to working on Catalyst, Tomas Doran (aka t0m) is the member of #london.pm with the silliest hair, and hacks code to move digital media round the world for a living.