Bitten by a Catalyst DWIM feature

ChrisDolan on 2007-03-04T05:45:45

I had a problem today with my Catalyst app that baffled me, but later led me to ponder how far do-what_I-mean (DWIM) code should go.

The problem

In Catalyst, you typically create data models in classes named like MyApp::Model::DB::author given a database table named 'author'. Then in controller code you say things like:

for my $author ($c->model('DB::author')->all) {
  ...
}


When I first started using Catalyst last fall, I discovered I could type "author" instead of "DB::author" and the code worked fine. I thought no further about it and saved myself four characters of typing for each model access. Cool!

Well, today I discovered that every time I accessed $c->model('question') I got errors about "No such column" in my 'instrument_question' join table. Huh? I checked my typing 10 times in both my controller code and my model code. Everything looked good. It should have been emitting SQL queries to the "question" table, not the "instrument_question" table.

So, I started reading code in lib/Catalyst/Model.pm and eventually lib/Catalyst.pm. I found that Catalyst has a DWIM feature that works like this: if you specify a model that doesn't exist, it treats your request as a regex and checks against all known models.

So that means that $c->model('question') became qr/question/i which matches "instrument_question" of course.

What amazes me most is that it took me 6 months of using Catalyst to figure out that I was typing my model names incorrectly.

The aftermath

So, this got me to thinking. What are the limits of DWIMmery? This code did a good job of fixing my error for a long time, but it never informed me that I was misusing the model() interface. Should it have warned? Perhaps just in -Debug mode?

More generally, when should DWIM code warn the programmer that they are using an interface in permitted but not-recommended fashion? Perl itself has issues like this, which Perl Best Practices and the Perl::Critic project are attempting to address.


DB::?

jjore on 2007-03-09T01:15:11

Is that "DB::foo" a perl namespace? You know that DB is reserved for perl's guts and debugger things, right? Some things magically change behavior if you put them into the DB:: namespace.

Re:DB::?

ChrisDolan on 2007-03-09T02:05:21

No, that's Catalyst shorthand for MyApp::Model::DB::*