.\" Automatically generated by Pod::Man 2.09 (Pod::Simple 3.04) .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. | will give a .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' .\" expand to `' in nroff, nothing in troff, for use with C<>. .tr \(*W-|\(bv\*(Tr .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .\" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .hy 0 .if n .na .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "PERLDEBTUT 1" .TH PERLDEBTUT 1 "2006-03-13" "DocFr" "User Contributed Perl Documentation" .SH "NAME/NOM" .IX Header "NAME/NOM" perldebtut \- Tutoriel de de\*'bogage de Perl .SH "DESCRIPTION" .IX Header "DESCRIPTION" Une (tre\*`s) le\*'ge\*`re introduction sur l'utilisation du de\*'bogueur de Perl, et un pointeur vers des sources d'information appronfondies disponibles sur le sujet du de\*'bogage des programmes perl. .PP Il y a un nombre extraordinaire de personnes qui semblent ne rien connai\*^tre de l'utilisation de de\*'bogueur de Perl, bien qu'ils utilisent ce language quotidiennement. Ceci est pour eux. .SH "Utiliser strict (use strict)" .IX Header "Utiliser strict (use strict)" Tout d'abord vous pouvez, sans utiliser le de\*'bogueur perl, mettre en oeuvre quelques ide\*'es pour vous simplifier la vie quand arrive le moment de de\*'boguer des programmes perl. En guise de de\*'monstration, voici un script simple, nomme\*' \*(L"salut\*(R", pre\*'sentant un proble\*`me\ : .PP .Vb 1 \& #!/usr/bin/perl \& \& $var1 = 'Salut le monde'; # toujours voulu faire cela :\-) \& $var2 = "$varl\en"; \& \& print $var2; \& exit; .Ve .PP Bien que ce script se compile et s'exe\*'cute gaiement, il ne va probablement pas faire ce que l'on en attend, c'est a\*` dire qu'il ne va pas du tout e\*'crire \&\*(L"Salut le monde\en\*(R"; il va en revanche faire exactement ce que nous lui avons demande\*' de faire, les ordinateurs ayant le\*'ge\*`rement tendance a\*` agir de cette manie\*`re. Ce script va donc e\*'crire un caracte\*`re de nouvelle ligne, et vous allez obtenir ce qui ressemble a\*` une ligne blanche. Il semble que le script ne contiennent que deux variables, alors qu'il en contient en fait trois (a\*` cause de la faute de frappe). .PP .Vb 3 \& $var1 = 'Hello World'; \& $varl = undef; \& $var2 = "\en"; .Ve .PP Afin de mettre en e\*'vidence ce type de proble\*`me, nous pouvons forcer la de\*'claration de chaque variable avant son utilisation en faisant appel au module X\ strict\ X par l'insertion apre\*`s la premie\*`re ligne du script de l'instruction 'use strict'. Maintenant, lors de l'exe\*'cution, perl se plaint de trois variables non de\*'clare\*'es, et nous obtenons quatre messages d'erreur car une variable est re\*'fe\*'rence\*'e deux fois\ : .PP .Vb 5 \& Global symbol "$var1" requires explicit package name at ./t1 line 4. \& Global symbol "$var2" requires explicit package name at ./t1 line 5. \& Global symbol "$varl" requires explicit package name at ./t1 line 5. \& Global symbol "$var2" requires explicit package name at ./t1 line 7. \& Execution of ./hello aborted due to compilation errors. .Ve .PP Merveilleux\ ! Et pour supprimer ces erreurs, nous de\*'clarons explicitement toutes les variables. Maintenant notre script ressemble a\*` ceci\ : .PP .Vb 2 \& #!/usr/bin/perl \& use strict; \& \& my $var1 = 'Salut le monde'; \& my $varl = undef; \& my $var2 = "$varl\en"; \& \& print $var2; \& exit; .Ve .PP Nous proce\*'dons alors a\*` une ve\*'rification de la syntaxe (toujours une bonne ide\*'e) avant d'exe\*'cuter a\*` nouveau le script\ : .PP .Vb 2 \& > perl \-c hello \& hello syntax OK .Ve .PP Et maintenant quand nous exe\*'cutons ce script, nous obtenons toujours \*(L"\en\*(R", mais au moins nous savons pourquoi. La compilation du script a re\*'ve\*'le\*' la variable '$varl' (avec la lettre 'l') et le simple changement de \f(CW$varl\fR par \&\f(CW$var1\fR re\*'soud le proble\*`me. .SH "Observer les variables et \-w et v" .IX Header "Observer les variables et -w et v" D'accord, mais comment faire lorsque vous souhaitez re\*'ellement voir vos donne\*'es, le contenu d'une variable dynamique, juste avant son utilisation\ ? .PP .Vb 2 \& #!/usr/bin/perl \& use strict; \& \& my $key = 'welcome'; \& my %data = ( \& 'this' => qw(that), \& 'tom' => qw(and jerry), \& 'welcome' => q(Hello World), \& 'zip' => q(welcome), \& ); \& my @data = keys %data; \& \& print "$data{$key}\en"; \& exit; .Ve .PP Tout semble correct. Apre\*`s avoir e\*'te\*' teste\*' avec la ve\*'rification de syntaxe (\fBperl \-c nom_du_script\fR) nous exe\*'cutons ce script et tout ce que nous obtenons est a\*` nouveau une ligne blanche\ ! Hmmmmm. Dans ce cas, une approche courante du de\*'bogage serait de parsemer de\*'libe\*'rement quelques instructions print, pour ajouter une premie\*`re ve\*'rification juste avant d'e\*'crire nos donne\*'es, et une seconde juste apre\*`s\ : .PP .Vb 3 \& print "All OK\en" if grep($key, keys %data); \& print "$data{$key}\en"; \& print "done: '$data{$key}'\en"; .Ve .PP Apre\*`s une nouvelle tentative\ : .PP .Vb 2 \& > perl data \& All OK \& \& done: '' .Ve .PP Apre\*`s s'e\*^tre use\*' les yeux sur ce code pendant un bon moment, nous allons boire une tasse de cafe\*' et nous tentons une nouvelle approche. C'est\-a\*`\-dire que nous appelons la cavalerie en invoquant perl avec l'option '\fB\-d\fR' sur la ligne de commande. .PP .Vb 2 \& > perl \-d data \& Default die handler restored. \& \& Loading DB routines from perl5db.pl version 1.07 \& Editor support available. \& \& Enter h or `h h' for help, or `man perldebug' for more help. \& \& main::(./data:4): my $key = 'welcome'; .Ve .PP Donc, ce que nous venons de faire ici est de lancer notre script avec le de\*'bogueur inte\*'gre\*' de perl. Celui-ci s'est arre\*^te\*' a\*` la premie\*`re ligne de code exe\*'cutable et attend notre action. .PP Avant de poursuivre plus avant, vous allez souhaiter connai\*^tre comment quitter le de\*'bugueur\ : tapez simplement la lettre '\fBq\fR', pas les mots \&'\fBquit\fR', ni '\fBexit\fR'. .PP .Vb 2 \& DB<1> q \& > .Ve .PP C'est cela, vous e\*^tes a\*` nouveau au paddock. .SH "Aide (help)" .IX Header "Aide (help)" De\*'marrer a\*` nouveau le de\*'bogueur et nous allons examiner le menu d'aide. Il y a plusieurs me\*'thodes pour afficher l'aide\ : taper simplement '\fBh\fR' affichera une longue liste de\*'roulante, '\fB|h\fR' (pipe\-h) redirigera l'aide vers l'afficheur page par page ('more' ou \&'less' probablement), et finalement, '\fBh h\fR' (h\-espace\-h) vous donnera un e\*'cran tre\*`s utile re\*'sumant les commandes\ : .PP .Vb 10 \& DB<1> h \& List/search source lines: Control script execution: \& l [ln|sub] List source code T Stack trace \& \- or . List previous/current line s [expr] Single step [in expr] \& v [line] View around line n [expr] Next, steps over subs \& f filename View source in file Repeat last n or s \& /pattern/ ?patt? Search forw/backw r Return from subroutine \& M Show module versions c [ln|sub] Continue until position \& Debugger controls: L List break/watch/actions \& o [...] Set debugger options t [expr] Toggle trace [trace expr] \& <[<]|{[{]|>[>] [cmd] Do pre/post\-prompt b [ln|event|sub] [cnd] Set breakpoint \& ! [N|pat] Redo a previous command B ln|* Delete a/all breakpoints \& H [\-num] Display last num commands a [ln] cmd Do cmd before line \& = [a val] Define/list an alias A ln|* Delete a/all actions \& h [db_cmd] Get help on command w expr Add a watch expression \& h h Complete help page W expr|* Delete a/all watch exprs \& |[|]db_cmd Send output to pager ![!] syscmd Run cmd in a subprocess \& q or ^D Quit R Attempt a restart \& Data Examination: expr Execute perl code, also see: s,n,t expr \& x|m expr Evals expr in list context, dumps the result or lists methods. \& p expr Print expression (uses script's current package). \& S [[!]pat] List subroutine names [not] matching pattern \& V [Pk [Vars]] List Variables in Package. Vars can be ~pattern or !pattern. \& X [Vars] Same as "V current_package [Vars]". i class inheritance tree. \& y [n [Vars]] List lexicals in higher scope . Vars same as V. \& e Display thread id E Display all thread ids. \& For more help, type h cmd_letter, or run man perldebug for all docs. .Ve .PP Plus d'options que vous ne le pensiez\ ! Ce n'est pas si terrible qu'il y parait, et il est tre\*`s utile et en plus amusant, d'en connai\*^tre plus a\*` propos de chacune de ces commandes. .PP Il y a quelques options utiles a\*` connai\*^tre imme\*'diatement. Vous pensez probablement que vous n'utilisez aucune bibliothe\*`que en ce moment, mais '\fBM\fR' va vous montrer les modules actuellement actifs, ceux appele\*'s aussi bien par le de\*'bogueur que par le script. De me\*^me, '\fBm\fR vous affichera les me\*'thodes et '\fBS\fR' tous les sous-programmes (par motif) comme ci\-dessous. '\fBV\fR' et '\fBX\fR' montrent les variables du programme range\*'es par package et peuvent e\*^tre restreintes par l'utilisation de motifs. .PP .Vb 5 \& DB<2>S str \& dumpvar::stringify \& strict::bits \& strict::import \& strict::unimport .Ve .PP L'utilisation de '\fBX\fR' et de ses cousins demande de ne pas utiliser l'identificateur de type ($@%), seulement le 'nom'\ : .PP .Vb 2 \& DM<3>X ~err \& FileHandle(stderr) => fileno(2) .Ve .PP Rappelez-vous que nous sommes dans notre minuscule programme avec un proble\*`me, nous devrions jeter un oeil pour voir ou\*` nous sommes et a\*` quoi nos donne\*'es ressemblent. Avant tout, regardons un peu de code autour de notre position actuelle (la premie\*`re ligne de code dans notre cas), gra\*^ce a\*` la lettre '\fBv\fR'\ : .PP .Vb 11 \& DB<4> v \& 1 #!/usr/bin/perl \& 2: use strict; \& 3 \& 4==> my $key = 'welcome'; \& 5: my %data = ( \& 6 'this' => qw(that), \& 7 'tom' => qw(and jerry), \& 8 'welcome' => q(Hello World), \& 9 'zip' => q(welcome), \& 10 ); .Ve .PP A\*` la ligne 4 se pre\*'sente un pointeur utile, qui vous indique ou\*` vous vous situez actuellement. Pour voir plus avant dans le programme, tapons encore '\fBv\fR'. .PP .Vb 9 \& DB<4> w \& 8 'welcome' => q(Hello World), \& 9 'zip' => q(welcome), \& 10 ); \& 11: my @data = keys %data; \& 12: print "All OK\en" if grep($key, keys %data); \& 13: print "$data{$key}\en"; \& 14: print "done: '$data{$key}'\en"; \& 15: exit; .Ve .PP Et si vous voulez lister a\*` nouveau la ligne 5, tapez 'l 5', (remarquez l'espace)\ : .PP .Vb 2 \& DB<4> l 5 \& 5: my %data = ( .Ve .PP Dans le cas de ce script, il n'y pas grand chose a\*` voir, mais il peut y avoir des pages entie\*`res a\*` explorer et '\fBl\fR' peut e\*^tre tre\*`s utile. Pour re\*'initialiser votre vue sur la ligne qui va s'exe\*'cuter, tapez un simple point \&'.'\ : .PP .Vb 2 \& DB<5> . \& main::(./data_a:4): my $key = 'welcome'; .Ve .PP La ligne affiche\*'e est la prochaine qui sera exe\*'cute\*'e, sans que cette exe\*'cution ne se soit produite pour l'instant. Donc bien que nous puissions imprimer une variable gra\*^ce a\*` la commande '\fBp\fR', tout ce que nous allons obtenir est une valeur vide (non de\*'finie). Ce que nous devons faire est exe\*'cuter la prochaine instruction exe\*'cutable en tapant '\fBs\fR'\ : .PP .Vb 7 \& DB<6> s \& main::(./data_a:5): my %data = ( \& main::(./data_a:6): 'this' => qw(that), \& main::(./data_a:7): 'tom' => qw(and jerry), \& main::(./data_a:8): 'welcome' => q(Hello World), \& main::(./data_a:9): 'zip' => q(welcome), \& main::(./data_a:10): ); .Ve .PP Maintenant, nous pouvons observer cette premie\*`re variable ($clef) .PP .Vb 2 \& DB<7> p $key \& welcome .Ve .PP La ligne 13 est celle ou\*` l'action a lieu, donc continuons notre progression gra\*^ce a\*` la lettre '\fBc\fR', qui insert un point d'arre\*^t 'a\*` usage unique' a\*` la ligne ou au sous-programme indique\*'. .PP .Vb 3 \& DB<8> c 13 \& All OK \& main::(./data_a:13): print "$data{$key}\en"; .Ve .PP Nous avons de\*'passe\*' notre ve\*'rification (ou\*` 'All \s-1OK\s0' e\*'tait imprime\*') et nous nous sommes arre\*^te\*'s juste avant le gros du travail. Nous pourrions essayer de lister quelques variables pour voir ce qu'il se passe. .PP .Vb 1 \& DB<9> p $data{$key} .Ve .PP Pas grand chose ici, observons notre hachage\ : .PP .Vb 2 \& DB<10> p %data \& Hello Worldziptomandwelcomejerrywelcomethisthat \& \& DB<11> p keys %data \& Hello Worldtomwelcomejerrythis .Ve .PP Bon, ceci n'est pas tre\*`s facile a\*` lire, et dans l'e\*'cran d'aide (\fBh h\fR), la commande '\fBx\fR' semble prometteuse\ : .PP .Vb 11 \& DB<12> x %data \& 0 'Hello World' \& 1 'zip' \& 2 'tom' \& 3 'and' \& 4 'welcome' \& 5 undef \& 6 'jerry' \& 7 'welcome' \& 8 'this' \& 9 'that' .Ve .PP Ceci n'aide pas beaucoup, deux 'bienvenue', mais sans que l'on sache s'ils correspondent a\*` des clefs ou a\*` des valeurs. Il s'agit juste de l'affichage d'une image d'un tableau, dans ce cas sans grande utilite\*'. L'astuce est ici d'utiliser une re\*'fe\*'rence a\*` la structure de donne\*'es\ : .PP .Vb 7 \& DB<13> x \e%data \& 0 HASH(0x8194bc4) \& 'Hello World' => 'zip' \& 'jerry' => 'welcome' \& 'this' => 'that' \& 'tom' => 'and' \& 'welcome' => undef .Ve .PP La re\*'fe\*'rence est re\*'ellement de\*'taille\*'e, et nous mettons finalement en e\*'vidence notre proble\*`me. Notre citation est parfaitement valide, mais errone\*'e pour notre propos, avec 'and jerry' traite\*' comme deux mots se\*'pare\*'s pluto\*^t que comme une phrase, donc entrai\*^nant un mauvais alignement des paires du hachage. .PP Le commutateur '\fB\-w\fR' nous aurait indique\*' ce proble\*`me si nous l'avions utilise\*' au de\*'part, et nous aurait e\*'vite\*' pas mal de soucis\ : .PP .Vb 2 \& > perl \-w data \& Odd number of elements in hash assignment at ./data line 5. .Ve .PP Nous re\*'parons notre citation\ : 'tom' =>q(et jerry), et exe\*'cutons a\*` nouveau notre programme. Nous obtenons alors le re\*'sultat attendu\ : .PP .Vb 2 \& > perl \-w data \& Bonjour le monde .Ve .PP Pendant que nous y sommes, regardons de plus pre\*`s la commande '\fBx\fR'. Elle est re\*'ellement utile et vous affichera merveilleusement le contenu de refe\*'rences imbrique\*'es, d'objet complets, de fragments d'objets, de tout ce que vous voudrez bien lui appliquer\ : .PP Construisons rapidement un objet, et e\-x-plorons le. D'abord, de\*'marrons le de\*'bogueur\ : il demande une entre\*'e a\*` partir de \s-1STDIN\s0, donnons-lui donc quelque chose qui n'engage a\*` rien, un ze\*'ro\ : .PP .Vb 2 \& > perl \-de 0 \& Default die handler restored. \& \& \& Loading DB routines from perl5db.pl version 1.07 \& Editor support available. \& \& \& Enter h or `h h' for help, or `man perldebug' for more help. \& \& \& main::(\-e:1): 0 .Ve .PP Maintenant construisez au vol un objet sur quelques lignes (notez l'antislash)\ : .PP .Vb 2 \& DB<1> $obj = bless({'unique_id'=>'123', 'attr'=> \e \& cont: {'col' => 'black', 'things' => [qw(this that etc)]}}, 'MY_class') .Ve .PP Et jetez un oeil dessus\ : .PP .Vb 10 \& DB<2> x $obj \& 0 MY_class=HASH(0x828ad98) \& 'attr' => HASH(0x828ad68) \& 'col' => 'black' \& 'things' => ARRAY(0x828abb8) \& 0 'this' \& 1 'that' \& 2 'etc' \& 'unique_id' => 123 \& DB<3> .Ve .PP Utile, n'est\-ce pas\ ? Vous pouvez utiliser eval sur n'importe quoi, et expe\*'rimenter avec des fragments de programme ou d'expressions re\*'gulie\*`res jusqu'a\*` ce que les vaches rentrent a\*` l'e\*'table\ : .PP .Vb 1 \& DB<3> @data = qw(this that the other atheism leather theory scythe) \& \& \& DB<4> p 'saw \-> '.($cnt += map { print "\et:\et$_\en" } grep(/the/, sort @data)) \& atheism \& leather \& other \& scythe \& the \& theory \& saw \-> 6 .Ve .PP Si vous voulez voir l'historique des commandes, tapez un '\fBH\fR'\ : .PP .Vb 7 \& DB<5> H \& 4: p 'saw \-> '.($cnt += map { print "\et:\et$_\en" } grep(/the/, sort @data)) \& 3: @data = qw(this that the other atheism leather theory scythe) \& 2: x $obj \& 1: $obj = bless({'unique_id'=>'123', 'attr'=> \& {'col' => 'black', 'things' => [qw(this that etc)]}}, 'MY_class') \& DB<5> .Ve .PP Et si vous voulez re\*'pe\*'ter une quelques commande pre\*'ce\*'dente, utilisez le point d'exclamation\ :'\fB!\fR'\ : .PP .Vb 9 \& DB<5> !4 \& p 'saw \-> '.($cnt += map { print "$_\en" } grep(/the/, sort @data)) \& atheism \& leather \& other \& scythe \& the \& theory \& saw \-> 12 .Ve .PP Pour plus d'informations sur les re\*'fe\*'rences, voyez les pages de manuel perlref et perlreftut. .SH "Pas a\*` pas dans le code" .IX Header "Pas a` pas dans le code" Voici un simple programme qui converti les degre\*'s Fahrenheit en Celsius (et vice\-versa). Ce programme pre\*'sente aussi un proble\*`me. .PP .Vb 2 \& #!/usr/bin/perl \-w \& use strict; \& \& my $arg = $ARGV[0] || '\-c20'; \& \& if ($arg =~ /^\e\-(c|f)((\e\-|\e+)*\ed+(\e.\ed+)*)$/) { \& my ($deg, $num) = ($1, $2); \& my ($in, $out) = ($num, $num); \& if ($deg eq 'c') { \& $deg = 'f'; \& $out = &c2f($num); \& } else { \& $deg = 'c'; \& $out = &f2c($num); \& } \& $out = sprintf('%0.2f', $out); \& $out =~ s/^((\e\-|\e+)*\ed+)\e.0+$/$1/; \& print "$out $deg\en"; \& } else { \& print "Usage: $0 \-[c|f] num\en"; \& } \& exit; \& \& sub f2c { \& my $f = shift; \& my $c = 5 * $f \- 32 / 9; \& return $c; \& } \& \& sub c2f { \& my $c = shift; \& my $f = 9 * $c / 5 + 32; \& return $f; \& } .Ve .PP Pour une raison inconnue, la conversion des Fahrenheit en Celsius ne donne pas le re\*'sultat escompte\*'. Voici ce que ce programme effectue\ : .PP .Vb 2 \& > temp \-c0.72 \& 33.30 f \& \& > temp \-f33.3 \& 162.94 c .Ve .PP Pas tre\*`s cohe\*'rent\ ! Nous allons placer manuellement un point d'arre\*^t dans le programme et exe\*'cuter celui-ci dans le de\*'bogueur pour voir ce qui se passe. Un point d'arre\*^t est un drapeau. Le de\*'bogueur va exe\*'cuter le programme sans interruption jusqu'a\*` ce drapeau. Quand il l'atteint, il arre\*^te l'exe\*'cution et pre\*'sente une invite pour la suite de l'interaction. En utilisation normale, ces commandes de de\*'bogage sont totalement ignore\*'es, et elle peuvent e\*^tre conserve\*'es en toute se\*'curite\*' dans le programme final, bien quelles en augmentent quelque peu le de\*'sordre. .PP .Vb 4 \& my ($in, $out) = ($num, $num); \& $DB::single=2; # insert at line 9! \& if ($deg eq 'c') \& ... \& \& > perl \-d temp \-f33.3 \& Default die handler restored. \& \& Loading DB routines from perl5db.pl version 1.07 \& Editor support available. \& \& Enter h or `h h' for help, or `man perldebug' for more help. \& \& main::(temp:4): my $arg = $ARGV[0] || '\-c20'; .Ve .PP Nous allons simplement descendre jusqu'a\*` notre point d'arre\*^t pre\*'de\*'fini gra\*^ce a\*` la commande '\fBc\fR'\ : .PP .Vb 2 \& DB<1> c \& main::(temp:10): if ($deg eq 'c') { .Ve .PP suivie par une commande '\fBv\fR' pour voir ou\*` nous sommes\ : .PP .Vb 11 \& DB<1> v \& 7: my ($deg, $num) = ($1, $2); \& 8: my ($in, $out) = ($num, $num); \& 9: $DB::single=2; \& 10==> if ($deg eq 'c') { \& 11: $deg = 'f'; \& 12: $out = &c2f($num); \& 13 } else { \& 14: $deg = 'c'; \& 15: $out = &f2c($num); \& 16 } .Ve .PP et par une commande '\fBp\fR' pour montrer le contenu des variables que nous utilisons\ : .PP .Vb 2 \& DB<1> p $deg, $num \& f33.3 .Ve .PP Nous pouvons placer un autre point d'arre\*^t a\*` n'importe quelle ligne commencant par un nume\*'ro suivi par deux points. Nous utiliserons la ligne 17, cette ligne e\*'tant la premie\*`re apre\*`s la sortie du sous-programme f2c. Nous pre\*'voyons de faire une pause a\*` cette endroit plus tard. .PP .Vb 1 \& DB<2> b 17 .Ve .PP Il n'y a pas d'indications en retour, mais vous pouvez voir les points d'arre\*^t place\*'s en utilisant la commande '\fBL\fR'. .PP .Vb 4 \& DB<3> L \& temp: \& 17: print "$out $deg\en"; \& break if (1) .Ve .PP Il est a\*` noter que les points d'arre\*^ts peuvent e\*^tre supprime\*'s en utilisant les commandes '\fBd\fR' ou '\fBD\fR'. .PP Nous allons alors continuer plus avant dans notre sous\-programme, cette fois en utilisant, a\*` la place du nume\*'ro de ligne, le nom du sous-programme suivi par la commande '\fBv\fR', maintenant familie\*`re, .PP .Vb 2 \& DB<3> c f2c \& main::f2c(temp:30): my $f = shift; \& \& DB<4> v \& 24: exit; \& 25 \& 26 sub f2c { \& 27==> my $f = shift; \& 28: my $c = 5 * $f \- 32 / 9; \& 29: return $c; \& 30 } \& 31 \& 32 sub c2f { \& 33: my $c = shift; .Ve .PP Notez que si il existait un appel a\*` un sous-programme entre notre position et la ligne 29, et si nous voulions traverser ce sous-programme pas\-a\*`\-pas, nous pourrions utiliser la commande '\fBs\fR'. Pour le franchir, il faudrait utiliser \&'\fBn\fR' qui exe\*'cuterait alors le sous-programme sans l'inspecter. Dans notre cas, nous continuons simplement jusqu'a\*` la ligne 29. .PP Regardons la valeur retourne\*'e\ : .PP .Vb 2 \& DB<5> p $c \& 162.944444444444 .Ve .PP Ce n'est pas du tout la re\*'ponse exacte, mais l'ope\*'ration semble correcte. Je me demande si le proble\*`me ne serait pas lie\*' aux priorite\*'s des ope\*'rateurs\ ? Essayons notre ope\*'ration avec quelques autres combinaisons de parenthe\*`ses. .PP .Vb 2 \& DB<6> p (5 * $f \- 32 / 9) \& 162.944444444444 \& \& DB<7> p 5 * $f \- (32 / 9) \& 162.944444444444 \& \& DB<8> p (5 * $f) \- 32 / 9 \& 162.944444444444 \& \& DB<9> p 5 * ($f \- 32) / 9 \& 0.722222222222221 .Ve .PP :\-) Ce dernier essai ressemble plus a\*` ce que l'on souhaite\ ! Bien, maintenant nous pouvons de\*'finir la variable a\*` renvoyer, et nous allons sortir de notre sous-programme gra\*^ce a\*` la commande '\fBr\fR'\ : .PP .Vb 1 \& DB<10> $c = 5 * ($f \- 32) / 9 \& \& DB<11> r \& scalar context return from main::f2c: 0.722222222222221 .Ve .PP Semble correct, continuons donc jusqu'a\*` la fin du script\ : .PP .Vb 5 \& DB<12> c \& 0.72 c \& Debugged program terminated. Use q to quit or R to restart, \& use O inhibit_exit to avoid stopping after program termination, \& h q, h R or h O to get additional info. .Ve .PP Une correction rapide de la ligne errone\*'e (insertion des parenthe\*`ses manquantes) dans le programme et nous avons termine\*'. .SH "Emplacement re\*'serve\*' pour a, w, t, T" .IX Header "Emplacement re'serve' pour a, w, t, T" Action, observation des variables, suivi des piles etc...: sur la liste des choses a\*` faire. .PP a .PP w .PP t .PP T .SH "Expressions rationnelles (ou regulie\*`res)" .IX Header "Expressions rationnelles (ou regulie`res)" Avez-vous jamais voulu savoir a\*` quoi ressemble une expression re\*'gulie\*`re\ ? Vous aurez besoin pour cela de compiler Perl avec le drapeau \&\s-1DEBUGGING\s0\ : .PP .Vb 10 \& > perl \-Dr \-e '/^pe(a)*rl$/i' \& Compiling REx `^pe(a)*rl$' \& size 17 first at 2 \& rarest char \& at 0 \& 1: BOL(2) \& 2: EXACTF (4) \& 4: CURLYN[1] {0,32767}(14) \& 6: NOTHING(8) \& 8: EXACTF (0) \& 12: WHILEM(0) \& 13: NOTHING(14) \& 14: EXACTF (16) \& 16: EOL(17) \& 17: END(0) \& floating `'$ at 4..2147483647 (checking floating) stclass `EXACTF ' \& anchored(BOL) minlen 4 \& Omitting $` $& $' support. \& \& EXECUTING... \& \& Freeing REx: `^pe(a)*rl$' .Ve .PP Vouliez-vous vraiment savoir\ ?:\-) Pour plus de de\*'tails sanglants sur la mise en oeuvre des expressions re\*'gulie\*`res, regardez les pages de manuel perlre, perlretut, et pour de\*'coder les e\*'tiquettes myste\*'rieuses (voir ci-dessus \&\s-1BOL\s0, \s-1CURLYN\s0 etc..), se re\*'ferer au manuel perldebguts. .SH "Conseils sur les sorties" .IX Header "Conseils sur les sorties" Pour obtenir toutes les sorties de votre journal d'erreur, et ne manquer aucun messages via les tampons du syste\*`me d'exploitation, inserez au de\*'but de votre script une ligne de ce type\ : .PP .Vb 1 \& $|=1; .Ve .PP Pour voir l'extre\*'mite\*' d'un fichier journal en croissance dynamique, tapez a\*` partir de la ligne de commande\ : .PP .Vb 1 \& tail \-f $error_log .Ve .PP Envelopper tous les appels a\*` 'die' dans une routine peut e\*^tre utilise\*' pour voir comment et a\*` partir de quoi ils sont appele\*'s. La page de manuel perlvar pre\*'sente plus d'informations\ : .PP .Vb 1 \& BEGIN { $SIG{_\|_DIE_\|_} = sub { require Carp; Carp::confess(@_) } } .Ve .PP Diverses techniques utilise\*'es pour la redirection des descripteurs \s-1STDOUT\s0 et \&\s-1STDERR\s0 sont explique\*'es dans les pages de manuel perlopentut et perlfaq8. .SH "CGI" .IX Header "CGI" Juste un petit truc pour tous les programmeurs \s-1CGI\s0 qui ne trouvent comment poursuivre apre\*`s l'invite 'waiting for input' quand ils exe\*'cutent leur script a\*` partir de la ligne de commande. Essayez quelque chose comme\ : .PP .Vb 1 \& > perl \-d my_cgi.pl \-nodebug .Ve .PP Bien su\*^r les pages de manuel \s-1CGI\s0 et perlfaq9 vous en dirons plus. .SH "Interfaces graphiques (GUI)" .IX Header "Interfaces graphiques (GUI)" L'interface de la ligne de commande est e\*'troitement inte\*'gre\*'e avec une extension a\*` emacs et il existe aussi une interface vers vi. .PP Vous n'avez pas a\*` faire tout ceci a\*` partir de la ligne de commande, il existe quelques possibilite\*'s d'utilisation d'interfaces graphiques. Ce qui est agre\*'able alors est de de pouvoir agiter la souris au dessus d'une variable et de voir apparai\*^tre dans une fene\*^tre approprie\*'e ou dans un ballon d'aide son contenu. Plus besoin de se fatiguer a\*` taper '\fBx \f(CB$nomdevariable\fB\fR' :\-) .PP En particulier, vous pouvez partir a\*` la chasse de\ : .PP \&\fBptkdb\fR Enveloppe pour le de\*'bogueur inte\*'gre\*' base\*'e sur perlTK .PP \&\fBddd\fR data display debugger (de\*'bogeur exposeur de donne\*'es) .PP \&\fBPerlDevKit\fR et \fBPerlBuilder\fR sont des outils spe\*'cifiques a\*` Windows \s-1NT\s0. .PP \&\s-1NB\s0. Plus d'informations sur ces outils ainsi que sur d'autres e\*'quivalents seraient appre\*'cie\*'es. .SH "Re\*'sume\*'" .IX Header "Re'sume'" Nous avons vu comment encourager de bonnes pratiques de programmation gra\*^ce a\*` l'utilisation de \fBuse strict\fR et de \fB\-w\fR. Nous pouvons exe\*'cuter le de\*'bogueur de perl (\fBperl \-d nomdescript\fR) pour inspecter nos donne\*'es gra\*^ce aux commandes \fBp\fR et \fBx\fR. Vous pouvez parcourir votre code, placer des points d'arre\*^t avec la commande \fBb\fR, parcourir ce programme pas a\*` pas avec \fBs\fR ou \&\fBn\fR, continuer avec \fBc\fR et revenir d'un sous-programme avec \fBr\fR. Pluto\*^t intuitif quand on y regarde de pre\*`s. .PP Il y a bien su\*^r beaucoup plus a\*` de\*'couvrir a\*` propos du de\*'bogueur, ce tutoriel n'ayant fait qu'en explorer la surface. La meilleure fac\*,on d'en apprendre plus est d'utiliser perldoc pour de\*'couvrir beaucoup d'autres d'aspects du langage, de lire l'aide en ligne (la page de manuel perlbug devrait e\*^tre votre prochaine lecture) et bien su\*^r d'expe\*'rimenter. .SH "VOIR AUSSI" .IX Header "VOIR AUSSI" Les pages de manuel perldebug, perldebguts, perldiag, perlrun, \fIdprofpp\fR. .SH "AUTEUR" .IX Header "AUTEUR" Richard Foley Copyright(c) 2000 .SH "CONTRIBUTIONS" .IX Header "CONTRIBUTIONS" Diverses personnes ont aide\*'es par leurs suggestions et leurs contributions, en particulier\ : .PP Ronald J Kimball .PP Hugo van der Sanden .PP Peter Scott .SH "TRADUCTION" .IX Header "TRADUCTION" .Sh "Version" .IX Subsection "Version" Cette traduction franc\*,aise correspond a\*` la version anglaise distribue\*'e avec perl 5.8.8. Pour en savoir plus concernant ces traductions, consultez . .Sh "Traducteur" .IX Subsection "Traducteur" Traduction initiale\ : Landry Le Chevanton . Mise a\*` jour\ : Paul Gaborit . .Sh "Relecture" .IX Subsection "Relecture" Ge\*'rard Delafond