ARCHIV |
|||||
Software (10844)
Distribuce (131)
Skripty (697)
Menu
Diskuze
Informace
|
Perl (35) - Vestavěný debuggerDnes převážně o možných příkazech debuggeru. Chyby v programech mohou být dvojího druhu. Syntaktické, na ty nás upozorní překladač, nebo logické. Laděním rozumíme hledání a odstraňování logických chyb. Nejčastějším nástrojem pro ladění jsou ladící tisky nebo debugger. Občas za nás také vyřeší mnoho práce pragma warnings (případně přepínač -w), který upozorňuje na sice syntakticky správné, ale nečekané zápisy. Vestavěnný debuggerKdyž spustíme Perl s přepínačem -d, program poběží v režimu debugger. Debuggerem rozumíme nástroj, který postupně krok po kroku prochází program, vypisuje informace o stavu proměnných v určitých okamžicích a umožňuje tak snadněji hledat chyby. Ovládání vestavěného debuggeruAbychom si mohli ukázat základní příkazy debuggeru, vytvoříme si krátký, ale pokud možno různorodý program. Dále budeme pracovat s následujícím kódem v souboru program.pl.
#!/usr/bin/env perl Nyní spusťme program.pl v debuggeru. $ perl -d program.pl Loading DB routines from perl5db.pl version 1.27 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(program.pl:4): my $prumer; DB<1> Debugger čeká na naše příkazy. Ale než-li se k nim dostaneme, objasněme si ještě význam promptu. Poslední dva řádky se skládají z několika údajů.
NápovědaPříkazem h se objeví seznam příkazů. Nápovědu k jednotlivým příkazům získáme příkazem h příkaz. Kompletní nápovědu získáme příkazem h h, případně |h h. Výpis kódu laděného programuPříkaz l vypisuje 10 řádků programu od aktuální pozice. Dalším zadáním příkazu l se zobrazí opět 10 řádků, ale až od místa, kde minulý výpis skončil. DB<1> 4==> my $prumer; 5 6: $prumer = nacti_data(); 7 8: pis_vysledky($prumer); 9 10 11 12 sub nacti_data { 13: my $prumer; DB<1> Pokud chceme vidět 6. řádek a nic okolo, použijme příkaz l 6. DB<1> l 6 6: $prumer = nacti_data(); DB<2> Je též možné určit řádky od do (příkaz l od-do, například pro řádky 2 až 6 l 2-6). Podobně lze získat daný počet řádků od dané pozice. Například příkaz l 3+5 znamená zobraz 3. řádek a dalších 5 za ním). K zobrazení deseti předcházejících řádků máme příkaz -. DB<2> l 1-5 1 #!/usr/bin/env perl 2: use strict; 3 4==> my $prumer; 5 DB<3> Řetězec ==> za číslem řádku v každém víceřádkovém výpisu ukazuje aktuální řádek. Deset řádků okolo aktuálního vypíšeme příkazem v. DB<3> v 1 #!/usr/bin/env perl 2: use strict; 3 4==> my $prumer; 5 6: $prumer = nacti_data(); 7 8: pis_vysledky($prumer); 9 10 DB<3> Hledání v kódu programuDebugger umožňuje hledat výskyty zadaého řetězce ve zdrojovém kódu. Směrem dopředu se hledá příkazem /řetězec/ a zpět příkazem ?řetězec?. Koncové / případně ? není povinné. DB<4> /prumer 8: pis_vysledky($prumer); DB<5> /prumer 13: my $prumer; DB<6> ?prumer 8: pis_vysledky($prumer); DB<7> KrokováníPříkaz s je jedním z vůbec nejzákladnějších příkazů debuggeru. Po jeho zadání se provede příkaz a řádek kódu se zároveň vypíše. Vykonává se skutečně jen jediný příkaz i přesto, že je řádek vypisován pokaždé celý (na řádku může být více než jeden příkaz). Pokud debugger narazí na podprogram, provádí se od prvního řádku stejně, jakoby byl rozepsán v hlavním programu. Podobnou funkci jako s má příkaz n. Chová se stejně až na to, že volání podprogramu bere jako každý jiný příkaz a nevstupuje do něj. Prázdný příkaz (stisk ENTER) zopakuje poslední příkaz s nebo n. DB<7> s main::(program.pl:6): $prumer = nacti_data(); DB<7> main::nacti_data(program.pl:13): my $prumer; DB<7> main::nacti_data(program.pl:14): print "Zadej prumer: "; DB<7> main::nacti_data(program.pl:15): $prumer = <STDIN> until ($prumer > 0); DB<7> Zadej prumer: 25 main::nacti_data(program.pl:16): return $prumer; DB<7> n main::(program.pl:8): pis_vysledky($prumer); DB<7> Obvod kruhu: 78.54 Obsah kruhu: 490.87 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. DB<7> Z výpisu je hezky vidět, že debugger data vypisuje a přijímá stejně jako kdybychom program normálně spustili. Pokud krokujeme v podprogramu a chceme, aby se zbytek kódu v něm provedl už bez krokování, slouží k tomu příkaz r. Dalším příkazem, který provádí kód je c [číslo_řádku|podprogram]. Ten provede program až po daný řádek nebo začátek daného podprogramu. c bez parametru provádí program do příští zarážky a nebo, pokud za aktuální pozicí žádná zarážka není, tak do konce. Restartujeme tedy provádění příkazem R a zkusíme provést vše až do 8. řádku. DB<7> R ... DB<7> c 8 Zadej prumer: 12 main::(deb.pl:8): pis_vysledky($prumer); DB<8> Příkaz c program provádí, ale implicitně nezobrazuje zdrojový kód. Příkazem t aktivujeme trasovací režim a poté už bude každý provedený příkaz vypisován. Výpis hodnotPomocí příkazu p se tiskne hodnota proměnné na výstup. Aktuální hodnotu proměnné $prumer dostaneme takto. DB<6> p "prumer=$prumer" prumer=12 DB<7> Dalšími příkazy k výpisu proměnných jsou X, V a x. X vypisuje proměnné definované v aktuálním balíku, V proměnné v balíku, uvedeném jako parametr. Příkaz x umí znázornit složitější strukturu. Je však třeba předat mu odkaz, protože v opačném případě zobrazí pouze výčet prvků. DB<44> x \%hash 0 HASH(0x8171874) 'klic1' => 'hodnota1' 'klic2' => 'hodnota2' 'klic3' => 'hodnota3' DB<45> Příkaz S vypisuje dostupné podprogramy. Bez parametru vypíše všechny. Jako parametr přijímá název balíčku (o balíčcích budeme hovořit hned po debuggingu). DB<3> S main main::BEGIN main::PI main::nacti_data main::pis_vysledky DB<4> Všechny používané moduly zobrazíme příkazem M. Nastavení proměnnýchPříkazem o zobrazíme seznam proměnných debuggeru a jejich hodnoty. Změnu některé proměnné provedeme příkazem o proměnná=hodnota. ZarážkyLze nastavit, aby se skript normálně vykonával do určitého místa, které je označeno zarážkou a poté se zastavil a čekal na další příkazy. Zarážku definujeme příkazem b číslo_řádku (zarážka se nastaví na číslo_řádku) nebo b název_podprogramu (zarážka se nastaví na první příkaz v zadaném podprogramu). Máme-li definované zarážky, zadáme příkaz c. Program se vykoná do řádku, na kterém je 1. zarážka a zastaví se. Dále můžeme opět krokovat nebo znovu stisknout c a dostat se na další zarážku. Takto jsme definovali zarážky, které budou zarážkami za všech okolností. Lze ale definovat zarážku, která bude zarážkou jen pokud bude platit nějaká podmínka. Například zadáme-li příkaz b 9 $p > 150, bude zarážka aktivní jen v případě, že na jejím místě bude hodnota proměnné $p větší než 150. Zarážky se mažou podobným způsobem, jen se místo b používá příkaz B. Všechny zarážky smažeme příkazem B *. DB<1> b 7 DB<2> b pis_vysledky DB<3> l 1-30 ... 6 7:b $prumer = nacti_data(); 8 ... 20 sub pis_vysledky { 21:b printf "Obvod kruhu: %6.2f\n", PI()*$_[0]; 22: printf "Obsah kruhu: %6.2f\n", PI()*($_[0]/2)**2; ... DB<4> c main::(deb.pl:7): $prumer = nacti_data(); DB<4> c Zadej prumer: 12 main::pis_vysledky(deb.pl:21): printf "Obvod kruhu: %6.2f\n", PI()*$_[0]; DB<4> c Obvod kruhu: 37.70 Obsah kruhu: 113.10 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. DB<4> AkceAkce je příkaz Perlu, který se provede na určitém řádku. Je to v podstatě zařazení nového kódu do programu. Příkaz na vytvoření akce je ve formátu a číslo_řádku příkaz. Akce se maže příkazem A číslo_řádku, všechny akce potom A *. DB<3> a 9 print "PRUMER: $prumer"; DB<4> n main::(deb.pl:7): $prumer = nacti_data(); DB<4> Zadej prumer: 54 main::(deb.pl:9): pis_vysledky($prumer); PRUMER: 54 DB<4> Proměnné pod kontrolouPomocí tzv. sledovaných výrazů (watch-expressions) si je možné nechat automaticky vypisovat hodnotu proměnné, jakmile se tato proměnná změní. Nastavuje se příkazem w proměnná. Kontrolu proměnné smažeme W proměnná, všechny už tradičně přidáním hvězdičky - W *. DB<3> w $prumer DB<4> n main::(deb.pl:5): my $prumer; DB<4> main::(deb.pl:7): $prumer = nacti_data(); DB<4> Zadej prumer: 21 Watchpoint 0: $prumer changed: old value: '' new value: '21 ' main::nacti_data(deb.pl:20): return $prumer; DB<4> Přehled nastaveníAbychom se v zarážkách, akcích a sledovaných výrazech neztratili, je zde příkaz L, který zobrazí všechna jejich nastavení. DB<26> L deb.pl: 6: $prumer = nacti_data(); break if (1) 13: my $prumer; action: $vysledek=15 23: printf "Obvod kruhu: %6.2f\n", PI()*$_[0]; break if ($prumer > 100) Watch-expressions: $stav $vysledek DB<26> Historie příkazůKurzorové šipky slouží k pohybu v historii příkazů. Navíc stejně jako v shellech je tu k dispozici vykřičník. Příkaz ! n provádí ntý příkaz a !! opakuje poslední příkaz. Parametrem vykřičníku může být i řetězec. V takovém případě je vykonán poslední příkaz, který na řetězec začíná. Posledních n příkazů historie vypíšeme příkazem H -n. Historie se maže příkazem H *. Stejně jako v shellech navíc funguje tabulátorová expanze. Externí příkaz shellu se spouští pomocí !!příkaz_shellu. Příkaz promptuLze nastavit, aby se spolu s promptem vždy zároveň provedl nějaký příkaz Perlu nebo debuggeru. V případě příkazů Perlu máme 2 možnosti - příkaz se může provádět před nebo po promptu. příkaz PerluPříkaz těsně před promtem se nastavuje zadáním < příkaz. Potřebujeme-li takových příkazů víc, další se přídává pomocí << příkaz. Příkazem < se zobrazí zdrojový kód všech takto nastavených příkazů. To samé ale až po promptu se nastavuje stejně, jen za < nahradíme >. příkaz debuggeruPro definici příkazu se používá příkaz {, jinak je mechanizmus analogický příkazům Perlu. V tomto případě nemá význam jestli je příkaz před nebo po manuálním zadání. AliasyPomocí příkazu = si je možné nastavit u často používaných příkazů aliasy. Vytvoříme si příkaz prumer, který bude mít stejný význam jako p "prumer=$prumer". DB<25> = prumer p "prumer=$prumer" prumer = p "prumer=$prumer" DB<26> prumer prumer=11 DB<27> Všechny nastavené aliasy zobrazíme příkazem =. Příkazy PerluDo promptu lze normálně psát i příkazy Perlu. U víceřádkových je nutné psát vždy před nový řádek zpětné lomítko. DB<10> for (1..5) { \ cont: print "CYKLUS: $_\n" \ cont: } CYKLUS: 1 CYKLUS: 2 CYKLUS: 3 CYKLUS: 4 CYKLUS: 5 DB<11> Modul Devel::DProfNakonec ještě zkusíme spustit program tímto příkazem.
$ perl -d:DProf program.pl
V aktuálním adresáři se vytvořil soubor tmon.out. Obsahuje informace, týkající se zatížení procesoru, které je pak schopen zobrazit příkaz dprofpp. Můžeme tak zjistit například náročnost jednotlivých podprogramů. Je též možné oba příkazy spojit a volat dprofpp -u -p program.pl. Více informací například v manuálu. V příštím dílu se podíváme na grafické debuggery, které lze použít pro ladění programů psaných v Perlu.
Související články
Předchozí Celou kategorii (seriál) Další
Perl (1) - Dávka teorie na úvod
Perl (2) - Úvod do syntaxe Perl (3) - Proměnné Perl (4) - Čísla a řetězce Perl (5) - Podmínky Perl (6) - Pravdivostní výrazy Perl (7) - Vstup poprvé Perl (8) - Některé základní vestavěné funkce Perl (9) - Cykly Perl (10) - Další řídící struktury Perl (11) - Pole - úvod Perl (12) - Pole - základní operace Perl (13) - Hashe Perl (14) - Další nástroje pro seznamy Perl (15) - Výchozí proměnná, heredoc, symbolické odkazy Perl (16) - Regulární výrazy - začínáme Perl (17) - Regulární výrazy - kotvy Perl (18) - Regulární výrazy - množiny znaků Perl (19) - Regulární výrazy - opakování a kvantifikátory Perl (20) - Regulární výrazy - magické závorky Perl (21) - Regulární výrazy - nahrazování Perl (22) - Regulární výrazy - přepínače Perl (23) - Regulární výrazy - rozšířené vzory Perl (24) - Regulární výrazy - příklady Perl (25) - Regulární výrazy - závěr Perl (26) - Podprogramy Perl (27) - Prototypy Perl (28) - Rozsahy platnosti proměnných Perl (29) - Úvod k práci se soubory Perl (30) - Práce se soubory Perl (31) - Testování souborů Perl (32) - Jiné typy souborů Perl (33) - Formátování výstupu - printf Perl (34) - Formátování výstupu - formáty Perl (36) - Grafické debuggery Perl (37) - Začínáme s moduly Perl (38) - Rozhraní modulu Perl (39) - Pragma Perl (40) - Dodatky k modulům Perl (41) - CPAN Perl (42) - Argumenty příkazového řádku Perl (43) - Přepínače Perl (44) - Dlouhé přepínače Perl (45) - Odkazy Perl (46) - Užití odkazů a anonymní data Perl (47) - Složitější datové struktury Perl (48) - Libovolně složité datové struktury Perl (49) - Tabulky symbolů a typegloby Perl (50) - Uzávěry a iterátory Perl (51) - Signály Perl (52) - Externí příkazy Perl (53) - Režim nakažení Perl (54) - Fork Perl (55) - Eval Perl (56) - Volby příkazu perl Perl (57) - Jednořádkové skripty Perl (58) - OOP - úvod Perl (59) - OOP - typické použití Perl (60) - OOP - dědičnost Perl (61) - OOP - přínos a užití dědičnosti Perl (62) - OOP - přetěžování Perl (63) - OOP - závěr Perl (64) - Projekt - čtečka sportovních výsledků Perl (65) - Projekt - získání dat Perl (66) - Projekt - výběr zápasů a podrobnosti Perl (67) - Projekt - dokončujeme modul Perl (68) - Projekt - zobrazení zápasů Perl (69) - Projekt - online přenos Perl (70) - Plain Old Documentation Perl (71) - Navazování proměnných Perl (72) - Navazování složitějších datových typů Perl (73) - DBM Perl (74) - Sockety Perl (75) - Obsluha více klientů Perl (76) - Síťová hra v kostky Perl (77) - Služby internetu Perl (78) - Databáze - úvod Perl (79) - Databáze - manipulace s daty Perl (80) - Databáze - závěrečné poznámky Perl (81) - CGI - příprava webového serveru Perl (82) - CGI - první skripty Perl (83) - CGI - získávání dat od uživatele Perl (84) - CGI - usnadnění tvorby skriptů pomocí modulu CGI Perl (85) - CGI - generování dokumentu modulem CGI Perl (86) - CGI - cookies Perl (87) - CGI - příklad aplikace Perl (88) - CGI - závěr Perl (89) - Mason - snadné psaní webů Perl (90) - Mason - speciální bloky Perl (91) - Mason - handlery Perl (92) - Mason - závěr Perl (93) - Catalyst - MVC framework pro Perl Perl (94) - Catalyst - základy pro psaní aplikace Perl (95) - Catalyst - šablony Perl (96) - Catalyst - spolupráce s databází Perl (97) - Curses - tvorba textových uživatelských rozhraní Perl (98) - Curses - pozicování a okna Perl (99) - Curses - měření rychlosti psaní Perl (100) - Curses - použití hotových widgetů Perl (101) - Curses - jednoduchý textový editor Perl (102) - Rozšiřování Perlu pomocí XS Perl (103) - Rozšiřování Perlu pomocí SWIG Perl (104) - Testování rychlosti Perl (105) - Testování programových jednotek Perl (106) - Debugování pomocí komentářů Perl (107) - Moose - moderní objektový systém Perl (108) - Moose - základní vlastnosti Perl (109) - Moose - role Perl (110) - Moose - meta API Perl (111) - Pokročilá práce se seznamy Perl (112) - Práce s PDF Perl (113) - Práce s archivy Perl (114) - Tk - úvod Perl (115) - Tk - umísťování widgetů Perl (116) - Tk - základní widgety Perl (117) - Tk - některé pokročilejší widgety Perl (118) - Tk - čas a události Perl (119) - Tk - CD man Perl (120) - Wx - základní práce s widgety Perl (121) - Wx - události Perl (122) - Gtk2 - úvod Perl (123) - Gtk2 - základní práce s obrázky Perl (124) - Gtk2 - události a čas Perl (125) - Gtk2 - vlastní widgety Perl (126) - Gtk2 - textové okno a práce s pozicemi Perl (127) - Gtk2 - hierarchické seznamy Perl (128) - Gtk2 - dialogy Perl (129) - Gtk2 - skládání widgetů Perl (130) - Gtk2 - menu a toolbary Perl (131) - Gtk2 - transparentní okna, tray ikona, výběr souborů Perl (132) - Gtk2 - drag&drop, druid Perl (133) - Gtk2 - úpravy vzhledu aplikací pomocí rc Perl (134) - Gtk2 - Glade Interface Designer Perl (135) - XML - čtení a zápis Perl (136) - XML - DOM a SAX přístupy Perl (137) - Vlákna Perl (138) - Memoizace - cachování podprogramů Perl (139) - Profilling - efektivní odhalování pomalých míst v programu Perl (140) - Profilling - píšeme si vlastní profiler / debugger Perl (141) - Formátování kódu, deparsování, perltidy Perl (142) - Způsoby konfigurování Perl (143) - Struktura datových typů, správa paměti Perl (144) - POE - událostmi řízené programování Perl (145) - POE - aplikace typu klient-server Perl (146) - Perl 6 - jazyk budoucnosti Perl (147) - Perl 6 - regulární výrazy, nové operátory Perl (148) - Perl Culture Perl (149) - Závěr Pozvánka na Český Perl Workshop Perl 5.22.0 a vše okolo Perl 5.24.0 a vše okolo Předchozí Celou kategorii (seriál) Další
|
Vyhledávání software
Vyhledávání článků
28.11.2018 23:56 /František Kučera 12.11.2018 21:28 /Redakce Linuxsoft.cz 6.11.2018 2:04 /František Kučera 4.10.2018 21:30 /Ondřej Čečák 18.9.2018 23:30 /František Kučera 9.9.2018 14:15 /Redakce Linuxsoft.cz 12.8.2018 16:58 /František Kučera 16.7.2018 1:05 /František Kučera
Poslední diskuze
31.7.2023 14:13 /
Linda Graham 30.11.2022 9:32 /
Kyle McDermott 13.12.2018 10:57 /
Jan Mareš 2.12.2018 23:56 /
František Kučera 5.10.2018 17:12 /
Jakub Kuljovsky | |||
ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2024) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze |