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

John Napiorkowski jjn1056 at yahoo.com
Fri Apr 28 21:52:49 CEST 2006


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.

package MyApp::Controller::testcontroller

##-- some standard setup code

sub new
{
   my ($self_str, $c_str ) = @_;
   my $self_obj = $self_str->NEXT::new(@_);

  ##--would like to do stuff like $c->log...

   return $self_obj;
}

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.

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.

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.

--john

--- Matt S Trout <dbix-class at trout.me.uk> wrote:

> John Napiorkowski wrote:
> > I spent a lot of time digging into the trouble
> with
> > using __PACKAGE__->config with subclassed
> controllers.
> >  The short story is that the solution from Matt
> (using
> > "__PACKAGE__->_config({ %{ __PACKAGE__->_config }
> > });") did work, although it's not so pretty since
> you
> > need to put it in front of EVERY controller that
> is
> > subclassing.
>  >
> > Although this solution does the trick, I looked
> into
> > this further, since I really think this solution
> is a
> > bit undesirable.  Personally I prefer to
> encapsulate
> > common behavior to base classes (as I am sure many
> of
> > you do) and having that line stuck in the top of
> every
> > controller is just going to cause me trouble
> sooner or
> > later.  For example I am sure that myself or
> another
> > programming will forget to do this, or not
> understand
> > why it is there in the first place and remove it.
> 
> Yes. That's why I was guiding you towards a test
> case we can commit to 
> Catalyst trunk and get this fixed in
> Catalyst::Component itself.
> 
> > The config method is inherited from
> > Catalyst::Component.  It's actually not a lot of
> > lines, so I'll just paste it here for our help:
> > 
> > sub config {
> >     my $self = shift;
> >     $self->_config( {} ) unless $self->_config;
> >     if (@_) {
>            my $orig_config = { %{$self->_config} };
> >         my $config = @_ > 1 ? {@_} : $_[0];
> >         while ( my ( $key, $val ) = each %$config
> ) {
> >             $orig_config->{$key} = $val;
> >         }
>            $self->_config($orig_config);
> >     }
> >     return $self->_config;
> > }
> 
> should be the fix.
> 
> > Anyway, at least I have a solution I can live with
> for
> > now.  Hopefully my post will save someone else the
> > trouble I had, and just maybe someone smarter than
> me
> > at this (most of you I imagine :) ) will read this
> and
> > have an 'ah ha' moment and grasp the trouble.
> 
> I already grasped the trouble. That's how I was able
> to give you a workaround :)
> 
> Can I have that test patch please?
> 
> -- 
>       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/ +
> 
> _______________________________________________
> Catalyst mailing list
> Catalyst at lists.rawmode.org
> http://lists.rawmode.org/mailman/listinfo/catalyst
> 


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 



More information about the Catalyst mailing list