[Catalyst-dev] Problems with $c->model() and _comp_singular()

Nathan Kurz nate at verse.com
Tue Aug 8 17:16:14 CEST 2006


On Tue, Aug 08, 2006 at 11:53:09AM +0100, Matt S Trout wrote:
> Nathan Kurz wrote:
> > I was just changing some things with my DBIx::Class schema's, and ran
> > into some problems that stumped me for a bit.  I had been calling
> > $c->model() and having it choose the correct model, but after I
> > rearranged the items in MyApp::Model::* things stopped working.  
> > 
> > I put in a debug statement like this:
> >   sub test : Local {
> >       my ($self, $c) = @_;
> >       $c->log->dumper('ref $c->model: ' . ref $c->model);
> >   }
> > And to my surprise found that $c->model made no sense at all:
> >   [debug] $VAR1 = 'ref $c->model: DBIx::Class::ResultSet';
> 
> That makes perfect sense - it'll be finding the first
> MyApp::Model::* in hash key order; if that happens to be a
> DBIC::Schema sub-model (i.e.  Model::DBIC::Foo) you'll get back a
> resultset as $c->model("DBIC::Foo") would return.

Thanks for your quick reponse, Matt!

Perhaps I mispoke when I said "made no sense".  I was able to figure
out what was happening, but didn't think that behaviour matched the
documentation of $c->model.  The behaviour might make sense if
'_comp_singular()' were named '_comp_first_in_hash()' and $c->model
were documented as such, but as it currently is I presumed it would
have died or returned nothing if multiple components matched, instead
of an apparently random component.

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

Do the last two lines here make sense as well?  If so, I think they
could maintain the same behaviour if the last line were changed to the
more transparent "return $rest || $comp".  For example:

  >  perl -e 'sub foo { my ($comp, $rest) = (1,2); \
                        return $comp unless $rest;} \
              print foo(). "\n";'
  > 2

But is the desired behaviour really to return the first hash-order
matching from component using the second element of @prefix if one is
found, otherwise to return the first hash-order matching item from the
first element of @prefix?  If it is, I think an explicit return value
might it clearer that this is the intended behaviour. :)

Nathan Kurz
nate at verse.com









More information about the Catalyst-dev mailing list