[Catalyst-dev] A bug in component resolution

Brian Cassidy brian.cassidy at nald.ca
Tue May 27 17:17:51 GMT 2008

Okay, here goes:

if you call $c->model() without having set default_model or 
current_model, the sub defaults to the following line of code:

return $c->_filter_component( $c->_comp_singular(qw/Model M/) );

_comp_singular() has the following at the end of sub:

my ( $comp, $rest ) =
     map { $c->_comp_search("^${appclass}::${_}::") } @prefixes;
return $comp unless $rest;

So, for both MyApp::Model and MyApp::M, it will do a search.

The test (unit_core_mvc.t) has the following 4 models defined:

MyApp::Model::Dummy::Model, MyApp::Model::M, MyApp::M::Model, and 

_comp_search will return the first component it finds. Thus, in 
_comp_singular(), we get (according to my tests, at least)

$comp = 'MyApp::Model::Test::Object=HASH(0xdeadbeef)
$rest = 'MyApp::M::Model'

The last line of that sub says "return $comp unless $rest;", so $comp 
isn't returned. But as all veteran perl programmers know, if you don't 
have an explicit return, then the last evaluated statement gets returned 
-- in this case, it's $rest.

In the test it checks for the following:

is (MyApp->model , 'MyApp::M::Model', 'model() with no defaults ok');

Which is wrong on so many levels, as _comp_singular should probably 
return an empty list if it gets multiple match -- but if it were to 
return a match, it should return the /first/ one, which is the 
Test::Object model.

All of this to say that component resolution currently stinks and is 
horribly busted. How can we fix this and move forward?


More information about the Catalyst-dev mailing list