Saturday, July 04, 2009

Is using the Catalyst 'forward' method a cargo cult?

I think most Catalyst new-commers believe that to execute a Catalyst action you need to forward to it - this is the effect of all the examples in the manual doing that instead of using the standard Perl syntax of calling a method on a class. Of course there are some differences between those two - but I am sure that for most cases the standard Perl way of doing it is perfectly enough.

And when it is not enough? What are really the differences between:

$c->forward( 'some_action' )

and the standard Perl:

$self->some_action( $c );

As far as I know the only two differences are that the first call is called in an eval and that it is logged in the debug output (if it is switched on), maybe there are some other minor differences, but, I am sure, nothing dramatical. It can helpful/needed sometimes (and othertimes that eval can be a nuisance), but it is also easy to add. Of course this is the simplest case - 'forward' signature is more complex and it does amazing things for finding the action "by it's private name" - but for most of the cases you ain't gonna need it and you can use ye old Perl syntax to make the call and spare yourself learning how to pass parameters to the forward call.

Related reading: Premature Flexibilization Is The Root of Whatever Evil Is Left - a reddit discussion.


phil jones said...

Might there not be another layer of indirection going on in that "forward"? Which is mediated by a config. file?

I'd agree that this might be overkill for many applications, but I guess if it's the standard in Catalyst, that's what it's there for. And it might be dangerous to mix the two styles, ie. directly call the Perl version in a project which expects to be called via forward.

zby said...

Yes it is another layer of indirection (but I don't know how a config could play a part in that), my argument is that what it buys us is too small for the cost of it and I would like to remove it from the status of 'standard'. I am not aware of any particular danger of calling actions directly beside those that I mention at the blog post (no eval and debug output) - but I am waiting for comments from more knowledgeable colleagues.

jayk said...
This comment has been removed by a blog administrator.
jayk said...

Mangled previous comment. Thanks for fixing zby.

Forward also supports calling chained actions. Chained dispatch is extremely useful and quite addictive once you start using it. Simply calling a method would not trigger all the parts of the chain and the method would fail.

For any action that is not 'private' forward ensures that the things that action expects have happened. You can shave a few CPU cycles by side-stepping it, but I have no doubt that in all but the simplest cases, you will spend many more brain cycles trying to figure out why something is misbehaving later.

I do agree, though, that method calls are perfectly fine for things that don't need to be Catalyst actions. I think this is an area that is somewhat misunderstood. Every method doesn't have to be an action. Catalyst is just Perl. If you don't need some piece of Catalyst in a particular case, there's no need to use it when plain ol' Perl will work just fine.