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

Brandon Black blblack at gmail.com
Tue Aug 8 17:34:45 CEST 2006


On 8/8/06, Nathan Kurz <nate at verse.com> wrote:
>
> 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.



The documented behavior of $c->model is that it requires either an argument,
or a configuration setting called "default_model".  If there is any flaw in
Catalyst.pm with regard to your issue, its that it isn't throwing an
exception when you call $c->model with no argument and no preset
"default_model".  The docs only indicate returning something with no
args/default for Views, not Models, and even then only if only a single View
exists.  With DBIC::Schema, a Model is created for every table, so you can't
have just one Model.


  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. :)


I haven't tested it myself to see if there's a problem here, but the
intended behavior is completely different than what you describe.  The
intended behavior is that _comp_singular return a component name if and only
if there's only a single matching component.  It should return nothing if
there's more than one match.

-- Brandon
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.rawmode.org/pipermail/catalyst-dev/attachments/20060808/3b0de333/attachment.htm 


More information about the Catalyst-dev mailing list