[Catalyst] Wierd config behavior solved (was Re: Creating my own controller....)

Matt S Trout dbix-class at trout.me.uk
Fri Apr 28 22:03:08 CEST 2006


John Napiorkowski wrote:
> Okay I grasp the issue now.  Sorry my email system is
> slow and I didn't see some of the responses until
> after I had emailed my last post.  I'll be happy to
> write a test case for this if it means I can help make
> catalyst better.
> 
> One thing that is still driving me crazy is this issue
> about when catalyst component methods recieve $self,
> $c, both, neither or some wierd combo.  Okay, I
> understand that if I mark a component method with one
> of the dispatcher attributes (:Local, etc.) that it
> always gets both $self and $c.  If I don't it just
> get's $self (as long as the method name is not trying
> to override an inherited one)
> 
> However the tricky place is when you are overriding
> methods.  For example, to return to the over-riding
> new example, after looking at the source for
> catalyst::componant one could reasonable think new
> accepts a $self and a $c obj.  However it doesn't
> really, it gets a string that names the self object
> and another that names the $c object.  I can see how
> to use NEXT to transform the string version of $self
> into a bless hash, but I can't see how to do the same
> with $c.
 >
> In the case above $c_str = 'MyApp', not a blessed hash
> as one would expect.  So I can't call any of the
> context methods on it without getting an error.  What
> is the best practices procedure to deal with this
> problem.

That's because components are initialised during application setup time. Once. 
Before there's a request. So there's not context object.

Class methods such as ->config, ->log, ->dispatcher and friends all work fine 
though.

> One thing I saw that some other people that wrote
> controllers and released them on CPAN was to use the
> "sub begin :Private" function.  This works for me but
> it has the disadvantage of running for each and every
> request, which exacts a performance penalty even if I
> can cache my results.  So I would prefer to not use
> that solution.  In any case I am really trying hard to
> grasp how and why Catalyst does these different things
> which is why I don't take such a solution.

sub begin :Private {
   my ($self, $c) = @_;
   unless ($self->{init_done}++) {
     $self->init($c);
   }
}

> Some of the suggestions I received helped me with
> similar problems on other methods, but I can't figure
> out what to do here.  One suggestion about using the
> ACCEPT_CONTEXT method seems a good possibility but to
> be honest after extensively search I can't find an
> example of this.  I went through the mailing list
> archives, the wiki and the source code for this but I
> couldn't find an example of how this is suppost to
> work.  If someone could point me somewhere in the
> right direction I would appreciate it.  If I could
> understand this I could even have some time to write
> about it on the wiki so that other's coming after me
> can find some help.

Basically, when ->model, ->view, ->controller, ->comp are called they all do

return $c->_filter_component($comp)

or equivalent. This does

if ($comp->can('ACCEPT_CONTEXT') {
   return $comp->ACCEPT_CONTEXT($c);
} else {
   return $comp;
}

pretty much. I think the only current public use of this is in 
Catalyst::Model::DBIC::Schema, which injects an ACCEPT_CONTEXT into the 
generate model classes so that

$c->model('BlogDB::Post')

returns a live resultset against that class rather than just the class (since 
the class doesn't have a reference to the $schema which holds the database 
connection, so it can't talk to the database on its own; this is because 
DBIx::Class is designed to allow more than one database connection against the 
same class tree without undue faffing since Class::DBI's inability to do this 
gracefully drove me up the bloody wall).

-- 
      Matt S Trout       Offering custom development, consultancy and support
   Technical Director    contracts for Catalyst, DBIx::Class and BAST. Contact
Shadowcat Systems Ltd.  mst (at) shadowcatsystems.co.uk for more information

+ Help us build a better perl ORM: http://dbix-class.shadowcatsystems.co.uk/ +



More information about the Catalyst mailing list