I started off writing some Perl code using Catalyst that looked like this:
package My::Controller;
extends 'Catalyst::Controller';
sub handler :Path :Args(0) :Location( some/url )
my ($self, $c) = @_;
$self->do_something_with_arguments($c);
$self->make_a_decision($c);
$self->another_method($c);
}
Then I thought . o O ( Why pass $c around all the time? ), and I changed to this:
package My::Controller;
extends 'Catalyst::Controller';
has c => (is => "rw", isa => "Catalyst");
sub handler :Path :Args(0) :Location( some/url )
my ($self, $c) = @_;
$self->c($c);
$self->do_something_with_arguments;
$self->make_a_decision;
$self->another_method;
}
There is only one entry point to the handler, so $self->c will always be set correctly.
My colleagues said that if this was how Catalyst was meant to be used then, well, everyone would use it like that. They were worried that doing it this way would cause a memory leak because the reference to $c would persist after the request was over. Is that true?
This isn't a "memory leak" in the exact sense that most people think of, since it won't result in unbounded memory growth, but yes, you're keeping a request context around longer than its ordinary lifetime. It'll be freed the next time you make a request that sets $self->c
to something else, but not any sooner. More importantly though, it's pretty much just wrong design. Either continue passing the context as an argument; or turn your controller methods into private actions and call them with ->forward
(which passes the context automatically); or move things into the model if appropriate, and have the model ACCEPT_CONTEXT
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With