[Catalyst] PathPart help

Dami Laurent (PJ) laurent.dami at justice.ge.ch
Mon Nov 19 08:41:06 GMT 2007


>-----Message d'origine-----
>De : Matt S Trout [mailto:dbix-class at trout.me.uk] 
>Envoyé : samedi, 17. novembre 2007 12:40

[ snip ]

>
>What I'd do instead is -
>
>package MyApp::ControllerBase::HasObject;
>
>sub has_object :PathPart('') :CaptureArgs(0)
>sub edit :Chained('has_user') :PathPart('edit') :Args(0)
>
>package MyApp::ControllerBase::ChainBase;
>
>__PACKAGE__->mk_accessors(qw(object_chains));
>
>__PACKAGE__->config(object_chains => []);
>
>sub COMPONENT {
>  my $new = shift->NEXT::COMPONENT(@_);
>  foreach my $chain (@{$new->object_chains}) { # commented 
>using example 'id'
>    my $action = $self->action_for($chain); # Catalyst::Action 
>for /foo/id
>    my $pkg = ref($new).'::'.ucfirst($chain); # 'id' -> 
>Controller::Foo::Id
>    {
>      no strict 'refs';
>      @{"${pkg}::ISA"} = 'MyApp::ControllerBase::HasObject'; # 
>inject base class
>    }
>    # Set :Chained('id') on Controller::Foo::Id->has_user
>    $pkg->config(actions => { has_object => { Chained => 
>$action->reverse } });
>  }
>  return $new;
>}
>
>package MyApp::Controller::Foo;
>
>use base qw(MyApp::ControllerBase::Chains);
>
>__PACKAGE__->config(object_chains = [ qw(id name email) ]);
>
>sub id ...
>sub name ...
>sub email ...
>
>Now, when Catalyst creates the Controller::Foo instance the 
>stuff after the
>component method will create Controller::Foo::Id, ::Name, 
>::Email - Catalyst
>will automatically pick this up (the same way it picks up the 
>sub-models
>created by e.g. Model::DBIC::Schema) and will load the 
>Foo/Id.pm etc. files
>afterwards -if- they exist.
>
>That way you'll get /foo/id/edit, /foo/name/edit etc. actions 
>which can be
>passed happily to $c->uri_for without ambiguity, and still have minimal
>repeated code.
>
>(Disclaimer: code typed straight into mail. probably at least 
>one typo or
>thinko lurking in there)
>
>If people like this approach, I could write it up as an advent 
>entry ...
>

Well, it may seem cute, but I am worried about long-term maintenance of this approach : if two years later somebody has to change anything in that setup, without knowing as much about Catalyst internals as you do Matt, then it could be quite hard for them to understand what is going on. 

The original Catalyst design of URL-method mappings was quite obvious to understand (Local, Global, Regex, etc.). Then came the chained actions, that gave us much more flexibility and reuse, but require quite a bit of reading and experiment to really understand them. Now if we add even more indirection levels, it will make it even harder to follow.

Two days ago at the French Perl Workshop somebody mentioned that Ruby on Rails has a notion of global, centralized dispatch table. Apache also has a convenient way to centralize the URL mappings, with <Location> or <LocationMatch> directives. As far as I know, Catalyst does not yet have any similar dispatch mechanism, but maybe that would be an interesting evolution path to investigate ?

Regards, Laurent Dami



More information about the Catalyst mailing list