Some more problems:
Issue #2 - Request (and Response) subclassing
This is a problem we encountered in Mason development as well, and I don't know of any great solutions.
The basic issue is that everyone wants a piece of the request (and response) class. It's the logical place to put app-specific per-request/response attributes & behavior. I note that the Catalyst docs seem to encourage you to do this:
{
package Catalyst::Request;
__PACKAGE__->mk_accessors('toejam');
sub foo { }
}
Naughty, naughty. This works fine for one app, but under mod_perl you might have a bunch (or a few) Catalyst apps sharing one interpreter, and the above is massively polluting.
The next solution you think of is subclassing a request. That works fine when you're writing an application. You subclass Catalyst::Request, let's call it VegGuide::Request, and add your new bits there.
This fails miserably if you want to distribute stuff on CPAN, however. A good example is Catalyst::Action::REST, which comes with its own request subclass. But what if there were also a Catalyst::Request::WhizBang that I wanted to use? I guess I could multiply-inherit in VegGuide::Request, but that gets really gross.
Another alternative is to encourage CPAN authors to distribute request/response class changes/improvements in the form of trait classes. Then in your app you can do this:
package VegGuide::Request;
use base 'Catalyst::Request';
use Class::Trait ( 'Catalyst::RequestTrait::REST' );
use Class::Trait ( 'Catalyst::RequestTrait::WhizBang' );
I guess that's no so different from multiple inheritance, really, but it feels saner, especially when those Catalyst::RequestTrait classes probably provide one or two attributes or methods each.
We came up with an entirely different solution in Mason, but this was before Class::Trait, and nowadays I'd probably go the trait route. For the curious, the Mason solution involves a method called alter_superclass(), and is well, really bizarre.
Traits (Score:2)
I haven't touched Catalyst in a long time, but when I did, I seem to recall that they implemented plugins via multiple inheritance. I urged them to consider something different, including a trait model. It would have been far more sane, but they were concerned (if I recall correctly) about backwards compatibility. Traits solve so many problems and I wish more people would take a look at them. Of course, it would help if I completely rewrote the Class::Trait documentation.
Re: (Score:1)
Of course, it would help if I completely rewrote the Class::Trait documentation.
Documentation... (Score:1)
Where does the documentation say that?
Ordinary morality is for ordinary people. -- Aleister Crowley
Re: (Score:2)
BTW, I'm on the Catalyst list if you want to move this discussion there.
Re: (Score:1)
Ordinary morality is for ordinary people. -- Aleister Crowley