[Catalyst] plugins; was Re: debug mode
Matt S Trout
dbix-class at trout.me.uk
Fri Jun 8 03:12:34 GMT 2007
On Thu, Jun 07, 2007 at 04:36:41PM -0700, Maurice Aubrey wrote:
> >Separating out the interrogation of the context and retrieval of data into
> >the ACCEPT_CONTEXT is how you avoid loose coupling - and it also then means
> >you know you have -one- method that requires a mocked $c to test rather
> >than potentially any in your entire codebase needing that.
> Avoid loose coupling? You mean tight?
Yes. Braino :)
> I was thinking you're basically pushing the mocked $c testing to the
> singleton class. If it works, then any code that uses it should work.
> The retrieval of the data is already handled for you (by the singleton).
> You just have to interrogate it, so one less piece.
But equally if I'm using the context I can always just pass it when I
instantiate the component I'm planning to test; if the context acquisition
code is inherited from some component with an ACCEPT_CONTEXT you only
need to test -that- once too.
> >>>It can be a bit more work up-front but it makes you think about your
> >>>architecture, which I find pays off down the road.
> >>A method call could also need to have access to other modules/packages
> >>it will delegate to. The singleton seems equivalent.
> >I don't do that either. I generally create associated objects via factory
> >methods and have an attribute for the related class with a default.
> >An example of this would be the _action_class member of
> >which is what defaults you to Catalyst::Action as your action class -
> >classes should -always- be overridable.
> There are lots of cases where you wouldn't do that though.
> Like if you need to make some directories, you're not going to have a
> new_file_path_like_object() methods and a default_file_path_class().
> You're just going to use File::Path.
I use Path::Class, and actually I usually have something like that hidden
behind a driver API that -does- abstract what class it produces.
> But your point being that you want your models to work with any
> Catalyst-type-thingy, rather than assuming it's part of your Catalyst
> application? Hmmm.
Well, for a start any Catalyst app. But I'll also for e.g. have scripts
where there's a concept of the "current user" but it gets passed explicitly
rather than pulled from $c->user by an ACCEPT_CONTEXT.
Also my components are often designed with the idea I may need to re-use them
in more than one app, at which point at the very least you need to parameterise
the application instance you call ->current_context (or whatever the method
might be called) on.
> So what do you think of things like Perl's @INC? How would you implement
> it without the equivalent of a singleton class?
> And if a class wanted to access it, would you write something equivalent
> to an ACCEPT_CONTEXT method that would be passed the Perl environment?
Lisp environments have already solved that one.
But there -is- a point where it makes sense to have something effectively
global and just use dynamic scoping (i.e. local *foo) to handle it.
I'm just expressing a preference to draw the line in a different place to
you, I think.
Matt S Trout Need help with your Catalyst or DBIx::Class project?
Technical Director Want a managed development or deployment platform?
Shadowcat Systems Ltd. Contact mst (at) shadowcatsystems.co.uk for a quote
More information about the Catalyst