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::? (Score:1)
Re: (Score:1)