Board logo

标题: 关于 Perl 调试器的结论 [打印本页]

作者: look_w    时间: 2018-4-15 18:07     标题: 关于 Perl 调试器的结论

Emacs 编辑器支持 Perl 调试器并使其更易于使用。您可以在 Emacs 中使用 Info(输入 M-x info)来阅读有关 GUD Emacs 的更详细信息。GUD 是与 Perl 调试器一起工作的全局调试方式(当在 Emacs 中编辑 Perl 程序时输入 M-x perldb)。
只需少量工作就可以让 vi 系列的编辑器也能支持 Perl 调试器。有关详细信息,请参阅 perldoc perldebug 页面。有关其它编辑器的信息,请参考每个编辑器的文档。
Perl 内置的调试器是一个强大的工具,可以执行比我们刚刚看到的简单用法复杂得多的任务。但它的确要求使用者具备大量 Perl 专门知识。正因为如此,我们现在要看一些简单些的工具,这些工具将更适合初级和中级 Perl 程序员。
Devel::ptkdb要使用 Devel::ptkdb 调试器,首先得从 CPAN(请        参阅下面的 )下载它并将它安装在您的系统上。(某些用户可能还需要安装 Tk 模块,该模块也可以从 CPAN 获得。)就我个人看来,Devel::ptkdb 在 UNIX 系统(如 Linux)上最好用。(虽然在理论上 Devel::ptkdb 并不限于与 UNIX 兼容的系统,但是,我从未听说过有人成功地在 Windows 上使用 Devel::ptkdb。正如一句老话所讲:除了滑雪穿过旋转门之外,任何事都是可能的。)      
如果无法让系统管理员为您安装(例如,因为您自己        就是系统管理员),可以尝试在命令提示行执行以下操作(可能需要以 root 身份执行这些操作):      
从 CPAN 安装 Devel::ptkdb
1
2
perl -MCPAN -e'install Tk'
perl -MCPAN -e'install Devel::ptkdb'




如果是第一次运行 CPAN 安装例程,那么,在回答一些初始问题之后,将自动下载并安装适当的模块。
可以用 ptkdb 调试器运行程序,如下所示(使用我们以前的 buggy.pl 示例):
使用 Devel::ptkdb
1
perl -d:ptkdb buggy.pl buggy.pl




要阅读 Devel::ptkdb 模块的文档,请使用命令 "perldoc Devel::ptkdb"。我们在本文中使用版本 1.1071。(虽然更新的版本可能随时问世,但它们与我们正在使用的版本应该没有很大的不同。)
将出现一个窗口,在该窗口的左侧是程序源代码,右侧是观察过的表达式列表(初始为空)。在 "Enter Expr:" 框中输入字 "$line"。然后单击 "Step Over" 按钮观察程序的执行情况。
"Run" 按钮将运行程序,直到运行完毕或到遇到断点为止。单击源代码清单窗口中的行号可以设置或删除断点。如果选择右侧的 "BrkPts" 选项卡,则可以编辑断点列表,并使它们受变量或函数的制约。(用这种方法设置条件断点非常简单。)
Ptkdb 还有 File、Control、Data、Stack 和 Bookmarks 菜单。这些菜单全部在 perldoc 文档中解释。因为 Ptkdb 使用起来如此方便,所以,它绝对是初级和中级 Perl 程序员的必备工具。甚至对于 Perl 高手,它也很有用(只要他们不告诉任何人他们正在使用那些新款图形界面)。
编写自己的 Perl shell有时使用调试器显得大材小用。例如,如果要与大型程序的其余部分        隔离来单独测试某些简单的代码,那么对于这种任务,调试器就显得过于复杂。这时,Perl shell 就派上用场了。      
当然还有其它一些有效的方法来实现 Perl shell,但是,我们将要看到的是一种常规的解决方案,该方案非常适用于大多数日常工作。一旦理解了这个工具,就应该可以随意地按照您的需要和喜好来修改它。
以下代码需要 Term::ReadLine 模块。使用几乎与 Devel::ptkdb 相同的方式从 CPAN 下载并安装它。
Perl shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/bin/perl -w
use Term::ReadLine;
use Data:umper;
my $historyfile = $ENV{HOME} . '/.phistory';
my $term = new Term::ReadLine 'Perl Shell';
sub save_list
{
my $f = shift;
my $l = shift;
open F, $f;
print F "$_\n" foreach @$l
}
if (open H, $historyfile)
{
@h = ;
chomp @h;
close H;
$h{$_} = 1 foreach @h;
$term->addhistory($_) foreach keys %h;
}
while ( defined ($_ = $term->readline("My Perl Shell> ")) )
{
  my $res = eval($_);
  warn $@ if $@;
  unless ($@)
  {
   open H, ">>$historyfile";
   print H "$_\n";
   close H;
   print "\n", Data:umper->Dump([$res], ['Result']);
  }
  $term->addhistory($_) if /\S/;
}




Perl shell 可以极好地完成几项工作,也可以较好地完成某些工作。
首先,它在您的主目录中名为 ".phistory" 的文件内保留一个唯一的、已经输入的命令历史记录。如果对同一条命令输入两次,将只保留一条命令(请参阅用于打开 $historyfile 并从中读取历史行的函数)。
每输入一条新命令,就将命令列表保存到 .phistory 文件中。因此,如果输入一条导致 shell 崩溃的命令,上一次会话的历史记录将不会丢失。
Term::ReadLine 模块使输入命令来执行更加容易。因为将命令限制成每次仅一行,所以可以将前面不错的 buggy.pl 编写为:
Perl shell 中的 buggy.pl
1
2
3
4
5
Da Perl Shell> use strict
$Result = undef;
Perl Shell> print "$_: " . <> foreach (0..20)
0: ...
1: ...




问题当然是 <> input 操作符最终会吃掉 shell 自己的输入。因此,不要在 Perl shell 中使用 <> 或 STDIN,因为它们会使事情更困难。您可以试一下这个:
Perl shell 中修复了错误的 buggy.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    Perl Shell> open F, "buggy.pl"
$Result = 1;
Perl Shell> foreach (0..20) { last if eof(F); print "$_: " . ; }
0: #!/usr/bin/perl -w
1:
2: use strict;
3:
4: foreach (0..20)
5: {
6:  my $line = <>;
7:  last unless defined $line;          # exit loop if $line is not defined
8:  print "$_ : $line";
9: }
$Result = undef;




如您所见,shell 可以使您轻松地将语句精简成一行。它还是非常普遍的一种隔离错误的解决方案,并提供了极好的学习环境。自己实践一下,看看是否可以自己编写一个 Perl shell 来进行调试,并看看您学到了多少。
构建工具库我们已经讨论了内置 Perl 调试器、Devel::ptkdb 和相关工具的最基本内容。还有很多调试 Perl 的方法。重要的是要理解调试过程:如何发现、解决和修复错误。当然,最重要的一点是确保深入理解程序的需求。
Perl 内置的调试器非常强大,但是它不适合于初级或中级 Perl 程序员。(Emacs 是个例外,只要理解了 Emacs 下的调试,那么即使对于初学者,它也可以称得上是一种有用的工具。)
目前为止,Devel::ptkdb 模块和调试器(因为它们的能力和易用性)是初级和中级程序员最好的选择。另一方面,Perl shell 是用于解决少量代码中孤立问题的个性化调试解决方案。
无论是带有 GUD 的 Emacs 编辑器,还是 Perl shell,或者是代码中的打印语句,每一个软件测试人员都构建自己的调试工具集。希望我们本文所讨论的工具可以将您的调试过程变得更轻松。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0