除了Data::Dumper
和之外,还有其他调试 Perl 程序的方法perl -d
吗?
18 回答
Perl 中有多种工具可用于调试和类似任务。
内置命令行调试器。
perl -d yourcode.pl
Andrew E. Page 的基于 Perl/Tk 的图形调试器。
这是一个在 Linux 和 Windows 上运行的免费工具,用Lisp 编写。源代码不可用。
Perl Regex 调试器和一篇由 Mark Jason Dominus 撰写的关于它的文章。
有很多东西可以帮助你:
- Devel::Trace - 打印执行的每一行
- Carp::REPL
*
-当代码抛出警告时进入 REPL - Devel::ebug - 一个可以从 Perl 代码控制的调试器
- Enbugger - 在运行时使用调试器,无论您的进程是否开始调试
我喜欢Devel::Trace。基本上,它会为您提供执行转储,向您显示代码路径。
另一方面,测试驱动的开发现在风靡一时,因此您也可能对像Devel::NYTProf这样的分析工具感兴趣,以进行高级测试。有关有趣的概述,请参阅此Tim Bunce 的博客文章。
我使用ActiveState Komodo进行逐步调试。
我个人更喜欢 ActiveState 版本。它看起来更加稳固和稳定,但它确实需要成本(而且工作正在为我付出代价)。如果是我的钱,那么我会使用 Eclipse 和 EPIC,因为它们是免费的。
最好的调试辅助工具是小例程、短范围、有限的副作用和大量测试。在它们孵化之前阻止它们。
我常用的工具范围是:
- 用于简单情况的打印语句和 Data::Dumper
- perl -d
这通常就足够了。有ddd ; 听说挺好玩的,没玩过。
对于某些任务(不是真正的调试,但接近它),我使用Devel::NYTProf。
有些人使用print
语句来查看程序部分中发生的事情,这些部分没有按照他们认为的代码执行。(即,作为在给定执行点检查变量中实际包含的内容的一种方式。)
根据您的操作,Log::Log4perl提供了一种简单的方法来管理调试的“打印”风格,尤其是在更大的应用程序中:
- 提供各种日志记录级别(调试、信息、错误、警告和致命)
- 从配置文件控制(例如,易于在开发盒上进行调试,仅在生产盒上出现错误)
- 由应用程序的部分配置(例如,一个日志文件中的 Web 应用程序在一个级别,另一个日志文件中的cron脚本在不同的日志级别)
- 按类可配置 - 轻松消除嘈杂的模块,或在应用程序深处添加详细调试
Test::More 用于编写基本测试,Hook::LexWrap、Test::MockObject、Test::Deep、Test::MockTime、Test::WWW::Mechanize 和许多其他用于高级测试。
Attribute::Signature 用于检查子参数。Carp::Assert 用于基于合约的编程。
可以使用Devel::Ebug::Wx 或 Devel::ptkdb(以及Padre中的更好支持)来更轻松地进行调试。
Emacs,放下手:
emacs my_script.pl
M-x perldb
Emacs 会提示你:
Run perldb (like this): perl my_script.pl
Hit enter (or add command line switches)
现在像往常一样使用调试器。
键入“c”以继续执行代码,它现在将在您执行时跟随您的代码。
Emacs 与它的调试器完全集成,这将使调试 Perl 代码几乎是微不足道的。
使用Devel::SimpleTrace进行最优雅的无缝无状态调试。
perl -MDevel::SimpleTrace -we'warn "main"; sub foo{ warn "outer"; sub { warn "inner" } }; foo()->()'
在开发过程中,我喜欢将 printf 语句嵌入到使用如下调试标志启用的战略位置(不是太多):
printf("h='$h', j='$j', ... (%d)\n", __LINE__) if $debug;
其中调试标志在脚本顶部定义:
my $debug = $ENV{DEBUG} || 0;
现在不必记住注释掉所有的 printf 行,我只需按如下方式运行脚本:
DEBUG=1 ./script.pl
当一切都准备好进行生产测试后,可以删除调试行:
cat script.pl | grep -v 'if $debug;'
如果你不喜欢,perl -d
那么Devel::REPL和Carp::REPL都是不错的选择。
就个人而言,我是Smart::Comments的忠实粉丝。它使追踪变得非常简单,也没有必要再次将其剥离。
use Smart::Comments -ENV;
...
sub myroutine {
my ($self, @args) = @_ ;
### args: @args
...
}
如果Smart_Comments
已在环境中设置,则以### 开头的行将转换为调试输出,并Dumper()
自动使用。如果未设置环境变量,则调试内容是完全惰性的。
它有很多功能,会产生进度条、警告、中止条件以及普通的旧调试输出。
适当的测试都是好的,我并不是在否定一个好的测试驱动开发(TDD) 开发方法,但是当试图找出现有错误的底部时,Smart::Comments是最好的选择。
一般我用
perl -d
用于调试。
您还可以为 Eclipse 使用Eclipse Perl Integration (EPIC) 插件。它提供了丰富的调试环境,并与 EPIC Perl 开发环境集成。您可以使用它,它通常很有帮助。
我认为编写测试主要可以减少调试时间。
CGI::Dump
Benchmark
Command-line options
__DATA__ & <DATA>
$.
__FILE__ & __LINE__
warn() & die()
Debug::Statements提供了一种简单的方法来插入和启用/禁用打印语句以进行调试。
d() 函数打印变量的名称、它的值和子例程名称。该实现已经过优化,以最大限度地减少程序员的击键。
以下是帮助您入门的示例代码:
my $myvar = 'some value';
my @list = ('zero', 1, 'two', "3");
my %hash = ('one' => 2, 'three' => 4);
use Debug::Statements;
my $d = 1;
d "Hello, World!";
d '$myvar';
d '@list %hash';
输出:
DEBUG sub mysub: Hello, World!
DEBUG sub mysub: $myvar = 'some value'
DEBUG sub mysub: @list = [
'zero',
1,
'two',
'3'
]
DEBUG sub mysub: %hash = {
'one' => 2,
'three' => 4
}
许多选项可用于自定义输出。完整的文档可以在CPAN上找到。