Subject: | problems with end() and auto() |
I've run into 2 problems while going through the tutorial. They might
just be misunderstandings on my part, but I believe that both point to
needed improvements in the tutorial code. Both took me quite a bit of
time to discover the problem and solution.
The most recent was with an end() action in Root.pm. Reading over the
tutorial, it stated that "end" was one of 5 "special, private" actions.
So, if it's a private action, I should be able to add the ":Private"
attribute, right? It already had ":ActionClass('RenderView')", which I
left in place, but also added ":Private". Unfortunately, that caused the
TT view to not be rendered, even though the 'template' key was set in
the stash, and the output was completely empty.
The other problem, now that I think of it, happened when I tried to
follow a tutorial in one of the Catalyst books that I've purchased, not
the online tutorial. I had an "auto" action which looked like this:
sub auto :Private { my($self, $c) = @_;
push(@{$c->stash->{matches}}, 'Root -> auto');
}
Well, I believe that all functions should have a "return" statement.
It's in the "Perl Best Practices" book, but more importantly, I believe
in it. So, I added a final "return;". Unfortunately, that caused the
entire response to be aborted - other actions should have been fired,
but they were not. It took me a long time to find out that if I removed
the "return;" (or replaced it with "return 1;"), everything started
working again. Realizing that Perl does some things that I consider very
bad, like functions that don't appear to return any values really do
return values, and functions return the last expression evaluated even
though you never asked for anything to be returned, here is what I think
is happening:
1. the call to push() returns something (probably the thing being
pushed, but perhaps the resulting list - who knows)
2. the call to auto() then returns that as the function return value,
even though there is no explicit return statement.
3. if the call to auto returns a false value, the entire response is
aborted. I'm sure that's documented somewhere, but I'm working on a
beginner's tutorial.
Point is - if the example code always returned a value explicitly when a
return value is used in any way, newbies (not a Perl newbie, but a
Catalyst newbie) wouldn't make these kinds of mistakes and spend a lot
of time trying to track down what happened.
Of course, if I entered the example code exactly as it is in the
tutorial files, I wouldn't have had these problems either. But then, I
want to understand what's going on and would rather enter code that
meets my usual programming standards.