【问题标题】:What are some good Perl debugging methods?有哪些好的 Perl 调试方法?
【发布时间】:2023-04-02 23:31:01
【问题描述】:

除了Data::Dumperperl -d,还有其他调试 Perl 程序的方法吗?

【问题讨论】:

    标签: perl debugging programming-languages cpan


    【解决方案1】:

    Available tools for debugging

    Perl 中有多种工具可用于调试和类似任务。


    内置命令行调试器。

    perl -d yourcode.pl
    

    Devel::ptkdb

    Andrew E. Page 的基于 Perl/Tk 的图形调试器。


    Regex Coach

    这是一个在 Linux 和 Windows 上运行的免费工具,用 Lisp 编写。源代码不是 可用的。


    Rx: A Regex Debugger for Perl

    Perl Regex 调试器和一篇由 Mark Jason Dominus 撰写的关于它的文章。


    A GUI for the Perl Debugger

    【讨论】:

    • + WishPerl - 也不错
    【解决方案2】:

    有些人使用print 语句来查看程序中没有执行他们认为代码会执行的操作的部分中发生了什么。 (即,作为在给定执行点检查变量中实际包含的内容的一种方式。)

    【讨论】:

    • 我喜欢使用“warn”而不是“print”,所以它会转到 stderr 而不是 stdout。 “print STDERR”也可以,但需要更多输入。
    【解决方案3】:

    我认为,编写测试主要可以减少调试时间。

    【讨论】:

      【解决方案4】:

      我常用的工具范围是:

      • 打印语句和 Data::Dumper 用于简单案例
      • perl -d

      这通常就足够了。有ddd;听说挺好玩的,没玩过。

      对于一些任务(不是真正的调试,但接近它)我使用Devel::NYTProf

      【讨论】:

      • 建议:s/Data::Dumper/Data::Dump/。更有营养。
      【解决方案5】:

      我喜欢Devel::Trace。基本上,它会为您提供执行转储,向您显示代码路径。

      另一方面,test-driven development 现在风靡一时,因此您也可能对像 Devel::NYTProf 这样的分析工具感兴趣,以进行高级测试。请参阅此Tim Bunce's blog post 以获得有趣的概述。

      【讨论】:

        【解决方案6】:

        我使用ActiveState Komodo 进行逐步调试。

        EclipseEPIC plugin 有一个逐步调试器。

        我个人更喜欢 ActiveState 版本。它看起来更加稳固和稳定,但它确实需要成本(而且工作正在为我付出代价)。如果是我的钱,我会使用 Eclipse 和 EPIC,因为它们是免费的。

        【讨论】:

          【解决方案7】:

          Test::More 用于编写基本测试,Hook::LexWrap、Test::MockObject、Test::Deep、Test::MockTime、Test::WWW::Mechanize 和许多其他用于高级测试。

          Attribute::Signature 用于检查子参数。 Carp::Assert 用于基于合约的编程。

          Devel::Ebug::Wx 或 Devel::ptkdb(很快会在Padre 中提供更好的支持)可用于更轻松的调试。

          【讨论】:

            【解决方案8】:

            有很多东西可以帮助你:

            • Devel::Trace - 打印执行的每一行
            • Carp::REPL - 当代码抛出警告时放入 REPL*
            • Devel::ebug - 一个可以通过 Perl 代码控制的调试器
            • Enbugger - 在运行时使用调试器,无论您的进程是否开始调试

            【讨论】:

            • * REPL = 读取、评估、打印循环(== 交互式解释器)
            【解决方案9】:

            根据您的工作,Log::Log4perl 提供了一种简单的方法来管理调试的“打印”样式,尤其是在大型应用程序中:

            • 提供各种日志记录级别(调试、信息、错误、警告和致命)
            • 从配置文件控制(开发箱容易调试,生产箱只有错误)
            • 可通过应用程序的各个部分进行配置(例如,Web 应用程序在一个日志文件中的一个级别,cron 脚本在另一个日志级别)
            • 可按类配置 - 轻松消除嘈杂的模块,或在应用程序深处的某处添加详细调试

            【讨论】:

            • 大多数人使用 Log::Log4perl 而 Log::Message(一个核心模块)可以使用。
            【解决方案10】:

            最好的调试辅助工具是小例程、短范围、有限的副作用和大量测试。在虫子孵化之前阻止它们。

            【讨论】:

              【解决方案11】:

              Some Other methods

              CGI::Dump
              
              Benchmark
              
              Command-line options 
              
              __DATA__ & <DATA> 
              
              $.
              
              __FILE__ & __LINE__ 
              
              warn() & die() 
              

              【讨论】:

                【解决方案12】:

                使用 Devel::SimpleTrace 进行最优雅的无缝无状态调试。

                perl -MDevel::SimpleTrace -we'warn "main"; sub foo{ warn "outer"; sub { warn "inner" } }; foo()->()'
                

                【讨论】:

                  【解决方案13】:

                  我一般用

                  perl -d
                  

                  用于调试。

                  您还可以为 Eclipse 使用 Eclipse Perl 集成 (EPIC) 插件。它提供了丰富的调试环境,并与 EPIC Perl 开发环境集成。您可以使用它,它通常很有帮助。

                  【讨论】:

                    【解决方案14】:

                    在开发过程中,我喜欢将 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;'
                    

                    【讨论】:

                      【解决方案15】:

                      如果您不喜欢perl -d,那么Devel::REPLCarp::REPL 都是不错的选择。

                      【讨论】:

                      • 可惜 Devel::REPL 需要 400 磅的 Moose(以及各种 MooseX 模块),而 Carp::REPL 依赖于 Devel::REPL
                      • 这是个问题,因为...?
                      【解决方案16】:

                      就个人而言,我是Smart::Comments 的忠实粉丝。它使追踪变得非常简单,也没有必要再次将其剥离。

                      use Smart::Comments -ENV;
                      ...
                      sub myroutine {
                          my ($self, @args) = @_ ;
                          ### args: @args
                          ...
                      }
                      

                      如果在环境中设置了Smart_Comments,则以### 开头的行将转换为调试输出,并自动使用Dumper()。如果没有设置环境变量,调试的东西是完全惰性的。

                      它有很多功能,会产生进度条、警告、中止条件以及简单的旧调试输出。

                      适当的测试都很好,我并没有拒绝一个好的 test-driven development (TDD) 开发方法,但是当试图找出现有错误的底部时,Smart::Comments是吧。

                      【讨论】:

                      • 它是一个源过滤器,因此很脆弱。
                      【解决方案17】:

                      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 代码几乎是微不足道的。

                      【讨论】:

                        【解决方案18】:

                        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 上找到。

                        【讨论】:

                          猜你喜欢
                          • 2010-11-27
                          • 1970-01-01
                          • 2011-06-29
                          • 2011-08-25
                          • 1970-01-01
                          • 2011-02-15
                          • 1970-01-01
                          • 2011-01-27
                          • 2011-09-12
                          相关资源
                          最近更新 更多