Perl 调试:程序员故障排除

作者:Paul Barry

当我第一次从 Linux Journal 总部收到 Martin Brown 的 Debugging Perl: Troubleshooting for Programmers 一书时,我的第一反应是:怎么可能有人写一整本书来调试 Perl 呢?一两章我可以想象,但是 一整本书?! 嗯,Martin Brown 确实设法写了一整本书,但这并不是一本完全关于调试的书。作者加入了很多额外的材料来充实内容,但稍后会详细介绍。

让我们先从统计数据开始。本书分为六个部分,14 章,一个附录,超过 400 页(不包括索引)。我现在将逐部分描述内容。

在一个简短的引言(称为“Introduction”)之后,第一部分“Perl 调试入门”包含一个单独的章节,(相当令人困惑地)也称为“Introduction”。(嗯...两个引言?这应该是我对即将到来的问题的第一条线索)。这个简短的章节向读者介绍了调试,并描述了可能困扰 Perl 程序的各种类型的错误。作者还介绍了这样一个观点,即在处理错误时,计划预防通常胜于治疗。他建议,更好的设计、好的代码编辑器、改进的代码格式和适当的注释可以在很大程度上避免首先引入错误。这是一个崇高的想法。然而,大多数 Perl 程序员会被这本书吸引,正是因为他们的代码中存在错误。被告知最好一开始就不要引入错误,这实际上没有任何作用(除了惹恼读者)。

第二部分“Perl 逻辑和语法”有五章,进一步扩展了作者“预防胜于治疗”的观点,并识别了编写 Perl 程序时可能出现的常见问题。第 2 章“基本 Perl 解析规则和陷阱”讨论了 Perl(解释器)在运行 Perl 程序时经历的过程。关于 Perl 内部工作原理的描述相当易读,比 perlguts 手册页更易读。但是,我不得不质疑将其纳入其中的理由,因为它通常只对从事 Perl 源代码工作的程序员感兴趣。在讨论完 Perl 内部原理之后,描述了 Perl 语法和解析规则,并参考了在对它们理解不充分时发生的常见错误。大多数 Perl 程序员会发现其中大部分材料都很熟悉。

第 3 章包含了一个常见的变量错误(或用作者的术语来说是“陷阱”)列表。同样,很多这些材料对于 Perl 程序员来说都很熟悉,特别是如果他们读过最新版的 Programming Perl (O'Reilly, 2000)。第 4 章以与第 3 章中变量相同的方式涵盖了语句和函数陷阱。这里真的没有什么新东西,而且表 4.1(从第 79 页开始)是对 Programming Perl 中“Functions”章节的重新整理和总结。

第 5 章“程序设计”只会引起 Perl 新手的兴趣。在这里,作者提出了他对如何最好地设计子例程、模块和对象的看法。本章还描述了一系列“节省时间的技巧”。这些材料总体上还可以,但是,它在关于调试的书里做什么呢?在我看来,有问题的材料包括在设计 Perl 子例程时讨论使用原型。作者认为原型是一件好事。然而,Perl 社区内部对此仍有争议,因为如果使用不当,原型有时会比它们带来的麻烦更多。一些著名的 Perl 程序员——例如 Tom Christiansen——已经公开反对原型的想法,并有记录表明了这一点。(请参阅 https://perldotcom.perl5.cn/pub/language/misc/fmproto.html 以获取有关此主题的讨论文件。)像作者在本章中所做的那样,建议始终使用原型是糟糕的建议。

本部分的最后一章“语言/平台迁移指南”首先列出了其他编程语言的用户在迁移到 Perl 时所犯的错误。但是,除了包含一组“Python 陷阱”之外,这些材料是对 perltrap 手册页的重新整理。也可以在 Programming Perl 的第 24 章中找到它。本章的第二部分描述了将 Perl 脚本从一个平台移植到另一个平台时可能出现的问题。与本书本部分中的大多数其他材料一样,这在其他地方也得到了充分的记录。

第三部分题为“错误捕获”,包含四章。第 7 章“基本错误捕获”涵盖了用于捕获和响应正在运行的 Perl 程序中的错误的机制。这些技术对于每个 Perl 程序员来说都很熟悉。在谈到内置的 warndie 子例程时,作者指出这些子例程“本质上……相同”,这是错误的。关于 carpcluckcroakconfess 子例程的讨论同样存在缺陷且令人困惑。在本章的结尾,展示了用于在 Tk 和 Web 应用程序中报告错误的代码示例。代码看起来足够令人印象深刻(尤其是 Tk 代码),但它似乎不合适,并且没有得到充分的解释。例如,第 159 页列出的 parse_template 子例程是做什么的?它看起来对代码至关重要,因为它被调用了三次,但在随附的文本中没有提及。第 8 章“使用编译指示和警告”是对 Programming Perl 第 31 章的重新整理。

最后,在 185 页之后,作者开始着手调试 Perl 代码。我曾希望关于调试的章节能够成为本书的救星。我期望看到的是一系列充满错误的 Perl 程序,作者将使用这些程序来演示各种调试技术。唉,事与愿违。

第 9 章“手动调试技术”首先描述了在代码中嵌入“print”语句以帮助发现错误的久经考验的技术。其他材料涵盖了 callereval 内置子例程的使用,以及使用信号和日志文件存储有关正在运行的程序的信息的方法。这实际上并不是调试(至少在我看来是这样),但是,在事后使用时,输出和日志可能会暗示问题所在。

第 10 章“Perl 调试器”介绍了标准命令行调试器(Perl 自带)以及 Windows 托管的 ActiveState 调试器。我无法评论 ActiveState 材料,但 Perl 调试器在 perldebug 手册页中有所记录,并且作者的处理并没有为该主题添加任何新内容。更糟糕的是,调试器的示例输出引用了上一章中介绍的一个程序,只是作者忽略了提及这一点,这让我(最初)有点困惑示例输出是如何生成的。当我弄清楚发生了什么事时,我惊讶地看到作者正在调试一个功能正常的程序,该程序不包含任何错误!本章的后半部分简要调查了 Perl 解释器可以生成的额外调试信息,假设它是使用调试标志构建的。与总的主题保持一致,很多这些材料都可以在 Perl 手册页中找到。

第四部分“优化您的代码”包含两章:“手动优化”和“自动优化”。手动章节介绍了一小部分更好的做事方式。这些材料中的大部分可以在其他地方找到。自动章节记录了 Perl Profiler 以及一系列 Perl 编译器和后端。现在,如果有人可以向我解释如何在调试过程中使用这两章中描述的优化技术,我将欣然接受它们包含在本书中。就目前而言(并且作为一个“如果它没坏,就不要修理它”的程序员),我不认为一本关于调试的书应该提及优化。其他人可能不同意我的观点。

第五部分“测试您的代码”包含题为“测试方法”和“破坏您的代码”的章节。关于测试方法的章节应该放在本书的更前面,否则,如果不是通过开发一套好的测试套件,程序员如何确定他们的软件中是否存在错误(在交付给用户之前)?不幸的是,这个重要的主题只得到了轻描淡写的处理,这很遗憾。破坏代码的章节再次让我挠头,想知道为什么这本书中会包含这样的材料。当我翻到最后一页时,我长长地叹了一口气,如释重负。除了附录,我完成了。

唯一的附录占据了本书的最后一部分(第六部分)。作者列出了 Perl 5.6.0 生成的所有错误消息的长列表,以及一些简短的评论。整个列表超过 60 页,与 Programming Perl 末尾出现的 60 页相同。这里和那里更改了一些词语,布局和呈现方式略有不同,但 内容是相同的! 这些材料也可以在 perldiag 手册页中找到,我怀疑 Programming Perl 的作者就是从那里获得的副本。不同之处在于 Programming Perl 的作者可能编写了在线文档(或参与了编写)。Brown 先生应该注明他的来源。

我很失望地发现,在 Debugging Perl: Troubleshooting for Programmers 中一直存在许多拼写错误和错误。例如,在第 66 页的最底部,当建议一种处理嵌套结构的技术时,作者提出了以下 Perl 代码行“为了清晰起见”

print join(', ',@{list}$hash{)

任何 Perl 程序员都会告诉您,这是 非法的。诚然,可能会犯错误,但这是一本关于 调试 的书……至少,读者期望所提供的代码能够工作!最令人尴尬的错误之一出现在作者介绍 C 程序员的陷阱时。在描述 C 中有但 Perl 中没有的内容时,在第 122 页的底部附近,您会发现:“C 中没有 switch 语句,尽管您可以在 Perl 中以多种不同的方式模拟它”……这对于世界各地的数百万 C 程序员来说将是新闻!几页之后,他提到了“perldelta main page”,而不是“manpage”。这些错误很容易通过拼写检查器(或文案编辑),但不应该通过技术编辑,也不应该通过作者。我讨厌说(但我忍不住):Debugging Perl: Troubleshooting for Programmers 本身也需要调试。出现这么多错误和拼写错误真的没有借口。很可能是作者屈服于匆忙填补 Perl 书籍市场中感知到的空白的压力。可悲的是,整个作品的整体质量受到了影响。

那么,我会向 Perl 社区推荐 Debugging Perl: Troubleshooting for Programmers 吗?嗯……这里确实有一些好的材料,但也有很多材料包含在其他地方可用和可访问的材料。经验丰富的 Perl 程序员(他们是本书目标受众的很大一部分)应该节省他们的 40 美元,并且(也许)等待经过大量修改的第二版,如果会有第二版的话。Perl 新手可能会从本书中获得更多,但需要保持警惕,因为文本中的错误可能会造成弊大于利,并且——至少——会使新手感到困惑。

我毫不怀疑 Martin Brown 了解他的 Perl。他是许多其他关于该语言的书籍的作者。只可惜,原本可以成为每个 Perl 程序员图书馆的必备补充的书籍,却被,嗯,搞砸了。

Paul Barry (paul.barry@itcarlow.ie) 在爱尔兰卡洛理工学院 (http://www.itcarlow.ie) 讲授计算机网络。他是 Programming the Network with Perl 的作者,该书将由 John Wiley & Sons 出版。

电子邮件:ljeditors@ssc.com

加载 Disqus 评论