http://qs1969.pair.com?node_id=507954

We've been working with Catalyst now for about a week.

I thought I'd share some observations, issues, theory, and praise.

Perhaps others starting out with Catalyst will find something here helpful.

Observations

  • Catalyst smartly leverages well-established perl technology. If you're not familiar with Class::DBI and (TT|Mason), it might be worth your while getting some of those concepts and idioms straight before diving into Catalyst (hereafter, "Cat"). We were fortunate to come to Cat from reasonably strong CDBI and Mason backgrounds.
  • The docs are sparse but good.
  • The Cat IRC channel is really solid. Thanks, sri.
  • Cat uses some automagicification, but not too much. (Say goodbye to  use statements!) Didn't bother any of our folks. Felt right.
  • Plugins are great. I was able to add in authentication to an intranet in about 10 mins. Persistent sessions in about 10 minutes. Amazing stuff.
  • The helper scripts are interesting. As we have our own "generate CDBI model from current dev DB schema" scripts, we didn't use them that much.
  • It is very easy to use your own Model.
  • While it is neat to use the Scaffolding framework to build a CRUD screen in 90 secs, they're ugly and simple, and we found ourselves hand-rolling a form displayer met our needs (eg present enum fields as pulldowns, present FK fields as pulldowns, present booleans as yes/no radio buttons, formatting, nice labels, help tooltips, etc.)

Issues

  • It'd be great to have Cat movies in English, with voice-over.
  • The biggest limitation to the docs is that they don't explain the model-view-controller paradigm yet. We asked lots of questions on the Cat IRC channel before getting that straightened out in our minds.
  • The other limitation of the docs is that we don't think they're up-to-date with the newest release... some features aren't doc'd yet.
  • It'd be great to add "M-V-C Theory 101" section to the docs.
  • When we wrapped our CDBI class in a Cat model, something somewhere was holding a reference to the CDBI object, and the app wasn't seeing commits. We've seen this before in other contexts. The problem went away when we started using our own CDBI model directly from our Cat apps, rather than wrapping the CDBI objects in a Cat package wrapper. (Not sure why we started with a wrapper, but we did.)
  • Sometimes we had trouble using $c->forward to reach a method in the same package... probably we specified the path wrong. In these cases we gave up and called the method as a method ($self->foo($c) rather than $c->forward('/we/had/the/path/wrong/foo')).
  • The Cat gang embrace TIMTOWTDI to an extreme. TIMTOWTDI is great, but for newcomers, some recommended practices / examples would be helpful, esp. on the topic of structuring an app (directories and actions) and M-V-C design strategy.

Theory

I didn't understand M-V-C. Here's my limited understanding so far. You may have different preferences or ideas. TIMTOWTDI, of course. But please share your thoughts on this -- I'm still learning this theory!
  • The model handles the database stuff. You want to fetch or make a persistent object? Ask the model. For us, model = CDBI. Since we already had a heavy solid feature-rich auto-generated CDBI framework in place (field checking, autodiscovery of has_a and has_many relationships, integrity constraints, etc), we've opted to use our CDBI classes as our Cat models with no additional wrapping. (See comment above about our issues with wrapping and commits, too.) So, the model is a way to hide the DB and the sql.
  • The View handles presentation stuff. The view makes it look nice, period. No heavy lifting or business logic in the view. Now, we're not adverse to the View using the Model to get more data for display. For example, say we pass an employeeid to the View via the cache, rather than an employee object; we're cool with the View fetching the Employee from the model. We'd not be cool with a View going off and changing the Employee in any way ("Hey, here's a raise!"). We also place trivial biz logic in the view, such as "only display active employees in the employee pulldown list" -- the View is empowered (understands the biz logic) to check the 'active' field in each Employee logic.
  • The Controller does the real work. Controller handles biz logic ("You can't give a raise to a fired employee"). The Controller handles the flow through the app. ("After user hits submit, check the form is OK, and if so, put into the DB and redirect to the next step, else place them back on the form with the bad fields highlighted in red.") At its essence, the controller is the app.
There were discussions on the Cat IRC channel about "thin controller, fat model" vs. "fat controller, thin model" -- we opted for the later.

Praise

Catalyst does indeed rock mightly.

High praise to the Catalyst team for a great piece of technology, which smartly employs MVC and wisely leverages CPAN.

If you're thinking about using a framework or have Ruby-On-Rails jealously, give Cat a few days to see if you like. Our shop did that; we do like it; we have small Cat intranet apps already in production and deployed after about a week.

Comments welcome, esp. on the theory of what-work-goes-where in an MVC framework.

water

Replies are listed 'Best First'.
Re: Catalyst : Observations After Week 1
by sauoq (Abbot) on Nov 12, 2005 at 18:26 UTC

    Great review! ++

    The Cat gang embrace TIMTOWTDI to an extreme. TIMTOWTDI is great, but for newcomers, some recommended practices / examples would be helpful, esp. on the topic of structuring an app (directories and actions) and M-V-C design strategy.

    I wholeheartedly agree. When I first started playing with Ruby on Rails, I immediately started to see some (much, even) wisdom behind their "convention over configuration" approach. Essentially, it's like building best practices right into the framework. You can do something differently if you want, but it's not usually in your best interest to do so. Then again, Rails is in some ways less flexible than I'd like, particularly when you have to work with an existing database. So, I don't think either framework has really hit the sweet spot on that issue. Making Rails more flexible may be harder than adding convention to Catalyst though, so that's probably a win for Cat.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: Catalyst : Observations After Week 1
by chromatic (Archbishop) on Nov 12, 2005 at 22:14 UTC
    The Controller does the real work. Controller handles biz logic ("You can't give a raise to a fired employee"). The Controller handles the flow through the app.

    I don't really consider that MVC. (It's just a pattern, so if that works for you, great! However, in my experience it's not the right approach.)

    The nice part about MVC, as I see it, is that you can re-use the model for different applications. That is, you have all of the business logic in one place. It's easy to see that you can change views, but if you have a different application that should allow fewer or different operations on the same data with the same underlying business rules, you can write a different controller.

    Again, it's just a pattern and how you use it depends on what you need to do.

      You can set up your Catalyst models to be just that. For many users, their Catalyst "Model" component is just a DBIx::Class or Class::DBI stepchild (with table-specific model-specific functions and whatnot) with a fancy module/class name. They reuse that same model code both from the Catalyst MVC framework and from other non-web components (like cron jobs doing database maintenance, or backend servers that log data to the same database the Catalyst app is viewing).
      I don't really consider that MVC. (It's just a pattern, so if that works for you, great! However, in my experience it's not the right approach.)

      Say more, please!

      Would you suggest this should live in the model, so other non-web-apps can call $obj->give_raise(or whatever) and for free get the logic ("no raises to fired emps", for example)?

      Suggestions?

      water

        Yes, exactly that.

        I once maintained a reporting application that pulled data from a multi-application database. There were no constraints or integrity checks in the database or the applications people used to enter or edit data.

        One day in 2003, my contact at the customer called me to yell that the report listed records from 2005! I told her that the reporting program had no hard-coded dates in it and that the errors came from her database. I also gave her a single SQL query to run to prove it. I'd previously given her another small application to find and correct as many data errors as safely possible -- and there were plenty.

        Granted, calling any of the applications MVC is a real stretch. Still it is painfully obvious that putting business logic (you can't add a record with a date in the future) where other applications can't reuse it can cause plenty of trouble.

        Of course, if you know that you'll never ever access your data with any other application ever, go ahead.

Re: Catalyst : Observations After Week 1
by marcus (Scribe) on Nov 12, 2005 at 20:35 UTC
    rather than $c->forward('/we/had/the/path/wrong/foo')). when you are in the same package, you can just $c->forward('foo'); ;)
    qw(marcus)
      Thanks! What are the disadvantages of the method call, vs. the forward?

      water

        With the forward, it acts as an eval cage, and catches any errors using the catalyst exception handling mechanism. Also, it will automatically pass along args to the next method, and it will show up in the application flow in debug mode.
        qw(marcus)
Re: Catalyst : Observations After Week 1
by zby (Vicar) on Nov 14, 2005 at 09:50 UTC
    There is a nice page on the wiki about this introductory stuff and particularly about the use of the MVC acronym in Cat. Personally I agree with nothingmuch at #catalyst irc channel:
    model should be the most complex reusable thing you can do without wasting time
    For me it means that business logic should go into the model - but there are people that use some other definition of business logic. Generally it is usefull to reuse the model class in cron job or some other administrative scripts.
      For me it means that the model represents a thing that does lots of work to make it easy to modify, but that it contains no decision making code whatsoever. High level business logic - the things that relate to the user (what data to retrieve for a request, what modifications on the model to do on behalf of the user), is in the controllers. Static policies, that are always enforced, like parameter validation, etc, can be mixed between the model and the controllers depending on context. The structure of the data is completely in the model.

      -nuffin
      zz zZ Z Z #!perl
        That is a common interpretation, but it is at odds with the traditional definition of MVC. Decisions, parameter checking, etc. all go in the model in MVC. The controller is just a generic thing that maps input (HTTP requests) to method calls.

        Most recent frameworks take this approach, making the model the dumb part (generic object-relational mapping layer) and putting all the application logic in the controller. It seems to work fine. Catalyst's controllers would probably be called part of the model by the traditional MVC definition, but it's just semantics after all.

Re: Catalyst : Observations After Week 1
by ghenry (Vicar) on Nov 12, 2005 at 22:04 UTC

    I forwarded a link of this node to the Catalyst mailing list, as it will be a good read for others too.

    Thanks,
    Gavin.

    Walking the road to enlightenment... I found a penguin and a camel on the way.....
    Fancy a yourname@perl.me.uk? Just ask!!!
Re: Catalyst : Observations After Week 1
by tphyahoo (Vicar) on Nov 14, 2005 at 08:37 UTC