[Catalyst] Authorization Failure

Tomas Doran bobtfish at bobtfish.net
Fri May 8 14:06:23 GMT 2009


Oleg Pronin wrote:
> How do i should in this case read my config in script context?

use Config::General manually..

> MyApp 
> initializes everything - memcached, dbic, uuid, json, etc.

Erm, yes, your config is gonna have memcached and dbic connection info 
in it..

I wasn't aware that generating UUIDs or JSON had enough state to want to 
initialize, but I may be wrong. ;)

Given you have your business/domain logic in your controllers, this 
makes perfect sense, and yes - it _is_ going to be hard to initialize 
stuff externally.

This is exactly why you separate everything into a model!

> By writing 'use MyApp' i get everything i need. Additionally, MyApp is 
> complex system which consists of a lot of modules (by means of C3) and 
> is not only a web framework.

Erm, I have no idea what you're talking about here? MyApp ISA Plugin1, 
Plugin2, Catalyst, method re-dispatch is through C3..

What plugins are you using which don't do anything web related, and why? 
(As they're probably a bad idea, and would be better as models)

> I would be nagged if i do not load Catalyst 
> at all, then i'll have to use every component from script directly 
> writing a lot of code instead of nice and short 'use MyApp'.

use MyModel;

MyModel->new(Config::General->new('myapp.conf')->getall->{"MyApp::MyModel"));

That isn't a lot of code?

If your actual domain model needs DBIC and/or memcached, then it's 
fairly easy to set things up such that you either pass in the relevant 
config (and MyModel creates the objects for you), or you pass in 
pre-built instances in construction, which your model then uses. (And 
you then generate the Catalyst::Model::MyModel using 
Component::InstancePerContext or similar)

The former is probably preferable, as if you have a layer over DBIC 
anyway, then your client code shouldn't be touching DBIC - that's 
violating the law of demeter.

> I'd say 
> than Catalyst is not _Web_ framework, it is _everything framwork_.

No, sorry - you're doing it wrong.

Catalyst is meant to be thin glue between web (or at least 
request/response) stuff, and your business logic and state storage.

Classes should _always_ be standalone and validate their own state.

I'm guessing that your DBIC classes are fairly thin, and a lot of the 
domain logic is in your controllers. This results in no separation of 
concerns, and an anemic domain model

Not only does this tie you implicitly to the web and make testing your 
code harder than it needs to be, it also ensures that you're breaking 
the single responsibility principle, gives you a great headstart for 
violating the law of demeter.

> In my 
> own opinion it is better to make a little difference for scripts
> (use MyApp { offline => 1 }) - which will not load web stuff and get 
> start lighter.

I'm not concerned with / thinking about how much code you're actually 
loading - that's a purely secondary concern.

The issue is that you're being forced to jump through hoops to make 
everything look like it is a web request, and the fact that you need not 
one but two classes to achieve any state change - a controller to 
validate that the state change is ok, and then the model to actually 
store the state change - meaning that the data and code needed to 
operate on whilst ensuring the data stays valid lives in different 
places, not nice....

> but framework will stay with many features for such 
> scripts - for example, automatic pid file with double execution prevent,

Catalyst doesn't do this for you?

> wrapping script for errors detection on log files and many other, i.e. 
> still framework-driven system,  not script-driven.

Erm, I'm not suggesting that you should be 'script driven', which I take 
to mean procedural ;)

All of my 'scripts' these days look like this:

package MyScript::Foo;
use Moose;
use MooseX::Types::Moose qw/Str/;
use namespace::autoclean;

with 'MooseX::Getopt';

has param1 => ( isa => Str, is => 'ro' );

sub run { # Do stuff here, usually a main loop, but delegating mostly to 
other methods}

__PACKAGE__->meta->make_immutable;
__PACKAGE__->new_with_options->run unless caller;

A 'script' does not mean you have to throw away good OO design..

Cheers
t0m



More information about the Catalyst mailing list