[Catalyst] An MVC logic separation conundrum

Aristotle Pagaltzis pagaltzis at gmx.de
Thu Mar 10 14:23:30 GMT 2016

* Chris Welch <welch.chris at gmail.com> [2016-03-10 14:05]:
> Thinking about it: any way you would pass in an anonymous sub rather
> than the return value from the actual methods - i.e.:
>     $match->generate_ical_data(
>         get_uri         => $c->uri_for_action( ... ) ,
>         get_description => $c->maketext( ... ) ,
>         # ...
>     );

I’m not sure what you’re asking. Do you mean you want to get rid of the
`sub { ... }` noise and just pass in “a method call”? If so, no, there
is no way of doing that in Perl.

Also, that would tie you to the signature of the Catalyst method. Which
may be OK, or may not be.

Using a closure allows you to write generate_ical_data generically and
keep the knowledge of how to translate that to Catalyst within the part
of your code that knows about Catalyst. Consider e.g.

    get_uri => sub {
        my ( $date, $event_id ) = @_;
        $c->uri_for_action( '/day/event', [ $date, $event_id ] );

Now generate_ical_data doesn’t have to hard-code the '/day/event' action
path. It doesn’t need to know anything about how URIs are made, it just
tells the closure which date and ID it needs a URI for, and the closure
produces one. That makes generate_ical_data easier to test too. Likewise
the closure might close over variables besides $c – maybe $self, or some
other lexical from the action method.

That’s what I meant when I used `...` in the example instead of just
writing `@_` to pass through the arguments. Using a closure gives you
control over what parameters are passed in what order, which doesn’t
have to be identical to the signature of the Catalyst method you wind
up calling.

This the same principle as the reason for having the controller, model
and view be separate from each other: isolating responsibilities.

Aristotle Pagaltzis // <http://plasmasturm.org/>

More information about the Catalyst mailing list