Does Anyone Else Hate the Stash?
When I first started using Perl Catalyst for web application development I felt appalled by how sloppy it seemed to pass important application data around in a secondary global namespace, the Catalyst Stash. I guess it's context global, but it stills seems messy to me in that it seems to poorly replicate features already built into Perl, and for which Perl can help you use correctly. I mean, a global is bad enough, but if you use strict and warnings you will at least get warned if you abuse a global, such as if you try to use it before it's initialized and all that. But the Stash is basically a Hash, and it's prone to typo issues, etc., basically all the evil stuff that I tried to banish from my Perl applications years ago.
It's one of those things that seems fundamentally busted to me, yet it works well enough for simple to medium cases. It just feels to me like it decouples control way too much, and in my experience the stash becomes a sort of no man's land.
I think it's one of the three things that bother me about Catalyst (with the ->forward/go/visit/detach versus method call ambiguity and the way the default TT view guesses a template based on the action name being the other two things that work acceptably enough but still manage to bother me quite a bit).
Thoughts? Am I being too controlling here? Should I just go with the flow or are there others out there that are also bothered by this?
Comments
I guess part of my problem is that the stash is like a catch all for so many different uses, and each use has pretty distinct needs. It leads to confusion. Like, with ->forward/detach/etc., you can place args in the call, like ->forward('Component', [@args]), OR you can stash stuff and then the forwarded to bit expects to find it in the stash, which seems really dangerous to me, in terms of how the stash can just have anything. You can really mix and match without any guidance as to what is the best thing to do.
I guess for the view you might need something more loosely defined, and it definitely avoids the also evil ...->view('TT', [\@somelist, {qw/hash of a very long list of keys and values}, 'more', $stuff]); Although lately I lean toward something like this over the stash, since I also allow the View to access models directly (in a readonly manner) since some MVC paradigms allow for this.
I was talking to a friend who works on rails, and the way he described rails is that any variable in scope of the action method is available in the template. I may be misrepresenting this some, but it seemed like a reasonable solution to me (kind of like the BindLex stuff that was popular a while back.) I don't see how that would really work for chained actions, though.
For passing stuff to the View, well, again I am of two minds here. Not all MVC paradigms require the View go through the Controller to get Model information. Many systems allow (and in some cases require) a View to listen in (read only) a Model, or some sort of UI Model adaptor for the complex cases. So really I'm thinking we could either load up info for the View in a true View class, using Moose style attributes, or as part of an initialization for a something like TT or Mason. That would lead us to having more than one View class in order for the View class to actually say what it needs. I know that's a big change from the way we handle this now, but maybe it's more managible in the end.
I am also not a big fan of chained and I think it should be replaced by something closer to the normal OO dispatch mechanism. The problem with chained and also it's power comes from joining two things: dispatching and parameters. I imagine there should be another way to mark the parts of the uri that are used for dispatching and use others as parameters.
My issue with chaining stems mostly from how much trouble I've seen it give junior and midlevel programmers. It's easy to mess up the chain, and typically not easy to figure out what you did wrong. Also, I find that building a chained action's url via $c->uri_for to be harder than it should. So lately I avoid it. But again, I know chaining is popular and the things I am complaining about are fixable with effort.