1Catalyst::Manual::TutorUisaelr::C0o7n_tDreibbuugtCgeaidtnagPl(ey3rs)lt:D:oMcaunmueanlt:a:tTiuotnorial::07_Debugging(3)
2
3
4

NAME

6       Catalyst::Manual::Tutorial::07_Debugging - Catalyst Tutorial - Chapter
7       7: Debugging
8

OVERVIEW

10       This is Chapter 7 of 10 for the Catalyst tutorial.
11
12       Tutorial Overview
13
14       1.  Introduction
15
16       2.  Catalyst Basics
17
18       3.  More Catalyst Basics
19
20       4.  Basic CRUD
21
22       5.  Authentication
23
24       6.  Authorization
25
26       7.  07_Debugging
27
28       8.  Testing
29
30       9.  Advanced CRUD
31
32       10. Appendices
33

DESCRIPTION

35       This chapter of the tutorial takes a brief look at the primary options
36       available for troubleshooting Catalyst applications.
37
38       Note that when it comes to debugging and troubleshooting, there are two
39       camps:
40
41       ·   Fans of "log" and "print" statements embedded in the code.
42
43       ·   Fans of interactive debuggers.
44
45       Catalyst is able to easily accommodate both styles of debugging.
46

LOG STATEMENTS

48       Folks in the former group can use Catalyst's "$c->log" facility.  (See
49       Catalyst::Log for more detail.) For example, if you add the following
50       code to a controller action method:
51
52           $c->log->info("Starting the foreach loop here");
53
54           $c->log->debug("Value of \$id is: ".$id);
55
56       Then the Catalyst development server will display your message along
57       with the other debug output. To accomplish the same thing in a TT
58       template view use:
59
60           [% c.log.debug("This is a test log message") %]
61
62       As with many other logging facilities, a method is defined for each of
63       the following "logging levels" (in increasing order of
64       severity/importance):
65
66           $c->log->debug
67           $c->log->info
68           $c->log->warn
69           $c->log->error
70           $c->log->fatal
71
72       You can also use Data::Dumper in both Catalyst code ("use Data::Dumper;
73       $c->log->debug("\$var is: ".Dumper($var));)") and TT templates ("[%
74       Dumper.dump(book) %]".
75

RUNNING CATALYST UNDER THE PERL DEBUGGER

77       Members of the interactive-debugger fan club will also be at home with
78       Catalyst applications.  One approach to this style of Perl debugging is
79       to embed breakpoints in your code.  For example, open
80       "lib/MyApp/Controller/Books.pm" in your editor and add the
81       "DB::single=1" line as follows inside the "list" method (I like to
82       "left-justify" my debug statements so I don't forget to remove them,
83       but you can obviously indent them if you prefer):
84
85           sub list :Local {
86               # Retrieve the usual Perl OO '$self' for this object. $c is the Catalyst
87               # 'Context' that's used to 'glue together' the various components
88               # that make up the application
89               my ($self, $c) = @_;
90
91           $DB::single=1;
92
93               # Retrieve all of the book records as book model objects and store in the
94               # stash where they can be accessed by the TT template
95               $c->stash->{books} = [$c->model('DB::Book')->all];
96
97               # Set the TT template to use.  You will almost always want to do this
98               # in your action methods.
99               $c->stash->{template} = 'books/list.tt2';
100           }
101
102       This causes the Perl Debugger to enter "single step mode" when this
103       command is encountered (it has no effect when Perl is run without the
104       "-d" flag).
105
106       NOTE: The "DB" here is the Perl Debugger, not the DB model.
107
108       If you haven't done it already, enable SQL logging as before:
109
110           $ export DBIC_TRACE=1
111
112       To now run the Catalyst development server under the Perl debugger,
113       simply prepend "perl -d" to the front of "script/myapp_server.pl":
114
115           $ perl -d script/myapp_server.pl
116
117       This will start the interactive debugger and produce output similar to:
118
119           $ perl -d script/myapp_server.pl
120
121           Loading DB routines from perl5db.pl version 1.3
122           Editor support available.
123
124           Enter h or `h h' for help, or `man perldebug' for more help.
125
126           main::(script/myapp_server.pl:16):      my $debug         = 0;
127
128             DB<1>
129
130       Press the "c" key and hit "Enter" to continue executing the Catalyst
131       development server under the debugger.  Although execution speed will
132       be slightly slower than normal, you should soon see the usual Catalyst
133       startup debug information.
134
135       Now point your browser to <http://localhost:3000/books/list> and log
136       in.  Once the breakpoint is encountered in the
137       "MyApp::Controller::list" method, the console session running the
138       development server will drop to the Perl debugger prompt:
139
140           MyApp::Controller::Books::list(/home/me/MyApp/script/../lib/MyApp/Controller/Books.pm:48):
141           48:         $c->stash->{books} = [$c->model('DB::Book')->all];
142
143             DB<1>
144
145       You now have the full Perl debugger at your disposal.  First use the
146       "next" feature by typing "n" to execute the "all" method on the Book
147       model ("n" jumps over method/subroutine calls; you can also use "s" to
148       "single-step" into methods/subroutines):
149
150             DB<1> n
151           SELECT me.id, me.title, me.rating, me.created, me.updated FROM book me:
152           MyApp::Controller::Books::list(/home/me/MyApp/script/../lib/MyApp/Controller/Books.pm:53):
153           53:         $c->stash->{template} = 'books/list.tt2';
154
155             DB<1>
156
157       This takes you to the next line of code where the template name is set.
158       Notice that because we enabled "DBIC_TRACE=1" earlier, SQL debug output
159       also shows up in the development server debug information.
160
161       Next, list the methods available on our "Book" model:
162
163             DB<1> m $c->model('DB::Book')
164           ()
165           (0+
166           (bool
167           __result_class_accessor
168           __source_handle_accessor
169           _add_alias
170           __bool
171           _build_unique_query
172           _calculate_score
173           _collapse_cond
174           <lines removed for brevity>
175
176             DB<2>
177
178       We can also play with the model directly:
179
180             DB<2> x ($c->model('DB::Book')->all)[1]->title
181           SELECT me.id, me.title, me.rating, me.created, me.updated FROM book me:
182           0  'TCP/IP Illustrated, Volume 1'
183
184       This uses the Perl debugger "x" command to display the title of a book.
185
186       Next we inspect the "books" element of the Catalyst "stash" (the 4
187       argument to the "x" command limits the depth of the dump to 4 levels):
188
189             DB<3> x 4 $c->stash->{books}
190           0  ARRAY(0xa8f3b7c)
191              0  MyApp::Model::DB::Book=HASH(0xb8e702c)
192                 '_column_data' => HASH(0xb8e5e2c)
193                    'created' => '2009-05-08 10:19:46'
194                    'id' => 1
195                    'rating' => 5
196                    'title' => 'CCSP SNRS Exam Certification Guide'
197                    'updated' => '2009-05-08 10:19:46'
198                 '_in_storage' => 1
199           <lines removed for brevity>
200
201       Then enter the "c" command to continue processing until the next
202       breakpoint is hit (or the application exits):
203
204             DB<4> c
205           SELECT author.id, author.first_name, author.last_name FROM ...
206
207       Finally, press "Ctrl+C" to break out of the development server.
208       Because we are running inside the Perl debugger, you will drop to the
209       debugger prompt.
210
211           ^CCatalyst::Engine::HTTP::run(/usr/local/share/perl/5.10.0/Catalyst/Engine/HTTP.pm:260):
212           260:            while ( accept( Remote, $daemon ) ) {
213
214           DB<4>
215
216       Finally, press "q" to exit the debugger and return to your OS shell
217       prompt:
218
219             DB<4> q
220           $
221
222       For more information on using the Perl debugger, please see "perldebug"
223       and "perldebtut".  For those daring souls out there, you can dive down
224       even deeper into the magical depths of this fine debugger by checking
225       out "perldebguts".
226
227       You can also type "h" or "h h" at the debugger prompt to view the
228       built-in help screens.
229
230       For an excellent book covering all aspects of the Perl debugger, we
231       highly recommend reading 'Pro Perl Debugging' by Richard Foley.
232
233       Oh yeah, before you forget, be sure to remove the "DB::single=1" line
234       you added above in "lib/MyApp/Controller/Books.pm".
235

DEBUGGING MODULES FROM CPAN

237       Although the techniques discussed above work well for code you are
238       writing, what if you want to use print/log/warn messages or set
239       breakpoints in code that you have installed from CPAN (or in module
240       that ship with Perl)?  One helpful approach is to place a copy of the
241       module inside the "lib" directory of your Catalyst project.  When
242       Catalyst loads, it will load from inside your "lib" directory first,
243       only turning to the global modules if a local copy cannot be found.
244       You can then make modifications such as adding a "$DB::single=1" to the
245       local copy of the module without risking the copy in the original
246       location.  This can also be a great way to "locally override" bugs in
247       modules while you wait for a fix on CPAN.
248
249       Matt Trout has suggested the following shortcut to create a local copy
250       of an installed module:
251
252           mkdir -p lib/Module; cp `perldoc -l Module::Name` lib/Module/
253
254       Note: If you are following along in Debian 5 or Ubuntu, you will need
255       to install the "perl-doc" package to use the "perldoc" command.  Use
256       "sudo aptitude install perl-doc" to do that.
257
258       For example, you could make a copy of Catalyst::Plugin::Authentication
259       with the following command:
260
261           mkdir -p lib/Catalyst/Plugin; cp \
262               `perldoc -l Catalyst::Plugin::Authentication` lib/Catalyst/Plugin
263
264       You can then use the local copy inside your project to place logging
265       messages and/or breakpoints for further study of that module.
266
267       Note: Matt has also suggested the following tips for Perl debugging:
268
269       ·   Check the version of an installed module:
270
271               perl -M<mod_name> -e 'print "$<mod_name>::VERSION\n"'
272
273           For example:
274
275               $ perl -MCatalyst::Plugin::Authentication -e \
276                   'print $Catalyst::Plugin::Authentication::VERSION;'
277               0.07
278
279           and if you are using bash aliases:
280
281               alias pmver="perl -le '\$m = shift; eval qq(require \$m) \
282                   or die qq(module \"\$m\" is not installed\\n); \
283                   print \$m->VERSION'"
284
285       ·   Check if a modules contains a given method:
286
287               perl -MModule::Name -e 'print Module::Name->can("method");'
288
289           For example:
290
291               $ perl -MCatalyst::Plugin::Authentication -e \
292                   'print Catalyst::Plugin::Authentication->can("user");'
293               CODE(0x9c8db2c)
294
295           If the method exists, the Perl "can" method returns a coderef.
296           Otherwise, it returns undef and nothing will be printed.
297

TT DEBUGGING

299       If you run into issues during the rendering of your template, it might
300       be helpful to enable TT "DEBUG" options.  You can do this in a Catalyst
301       environment by adding a "DEBUG" line to the "__PACKAGE__-"config>
302       declaration in "lib/MyApp/View/TT.pm":
303
304           __PACKAGE__->config({
305               TEMPLATE_EXTENSION => '.tt2',
306               DEBUG              => 'undef',
307           });
308
309       There are a variety of options you can use, such as 'undef', 'all',
310       'service', 'context', 'parser' and 'provider'.  See Template::Constants
311       for more information (remove the "DEBUG_" portion of the name shown in
312       the TT docs and convert to lower case for use inside Catalyst).
313
314       NOTE: Please be sure to disable TT debug options before continuing with
315       the tutorial (especially the 'undef' option -- leaving this enabled
316       will conflict with several of the conventions used by this tutorial to
317       leave some variables undefined on purpose).
318
319       Happy debugging.
320

AUTHOR

322       Kennedy Clark, "hkclark@gmail.com"
323
324       Please report any errors, issues or suggestions to the author.  The
325       most recent version of the Catalyst Tutorial can be found at
326       http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Manual/5.80/trunk/lib/Catalyst/Manual/Tutorial/
327       <http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-
328       Manual/5.80/trunk/lib/Catalyst/Manual/Tutorial/>.
329
330       Copyright 2006-2008, Kennedy Clark, under Creative Commons License
331       (http://creativecommons.org/licenses/by-sa/3.0/us/
332       <http://creativecommons.org/licenses/by-sa/3.0/us/>).
333
334
335
336perl v5.12.0                      20C1a0t-a0l2y-s1t7::Manual::Tutorial::07_Debugging(3)
Impressum