我如何警告`perl -c`中的函数用法?

Ste*_*sky 5 debugging perl compiler-warnings

我们的代码库包括各种只应用于测试的调试钩子.作为说明性示例:

sub example {
   my ($arg) = @_;
   my $result = do_something_with($arg);
   debug_dump_values($arg); # debugging code
   return $result;
}
Run Code Online (Sandbox Code Playgroud)

当然,不应提交(甚至部署)此类调试代码.有没有办法在运行此代码时生成警告perl -c?有点像

Debug function debug_dump_values() called at example.pl line 4.
Run Code Online (Sandbox Code Playgroud)

这可以作为运行时警告实现:

sub debug_dump_values {
    carp "Debug function debug_dump_values() called";
    ...
}
Run Code Online (Sandbox Code Playgroud)

但是我希望通过语法检查插件在我的文本编辑器中显示警告,因此它需要是一个"编译时"警告.

Sob*_*que 1

我认为这不是一件容易完成的事情——如果不对编码风格进行一些重大的调整,这是不可能实现的。

我能想到的方法:

将您的“调试”代码放入单独的模块中。

在模块中嵌入一条警告,指示其已启用 - 嵌入“BEGIN”块中。(这不一定会告诉您正在调用哪个子程序,也不一定会告诉您在哪里调用)

例如

BEGIN { 
    carp "Debugging module is imported" 
}
Run Code Online (Sandbox Code Playgroud)

这样做的优点可能是 - 您可以拥有“调试”和“非调试”模块,并且在这两个模块中具有相同的子模块。“不调试”将放入虚拟潜艇。

然后,您可以用来B::Lint验证您的模块并检查 subs 是否全部定义:

perl -MO=Lint[,OPTIONS] foo.pl

undefined-subs This option warns whenever an undefined subroutine is invoked. This option will only catch explicitly invoked subroutines such as foo() and not indirect invocations such as &$subref() or $obj->meth() . Note that some programs or modules delay definition of subs until runtime by means of the AUTOLOAD mechanism

通过参考分配您的子系统。

编辑:并不像我想象的那样工作 - 有一个声明匿名子并在“BEGIN”块内创建引用的概念 - 这并不像我想象的那样工作 - 它只会在运行时出错,因为你会得到以下错误范围。

我能提供的最好的是:

use strict;
use warnings;

my $debug = 1;

##debug code bit. 
#Comment out if not needed
my $debug_sub = gimme_debug();

sub gimme_debug {
    if ( $debug ) { 
        warn "Debugging enabled\n"; 
        return sub { print "Got values of :", @_, "\n"; };
    }
    else { warn "Debug subroutine defined with debug disabled!" };
}

#... way down code ... 

&$debug_sub ( "Some input" );
Run Code Online (Sandbox Code Playgroud)

如果删除 的声明,那么您将收到编译时警告,因为$debug_sub未声明。这可以与上面的结合起来,例如将其捆绑在模块或对象中。

自动化测试

它并没有具体执行您所询问的内容,但您无论如何都可能需要考虑它。对您的代码/模块进行自动测试。例如,使用TAP::Harness. 这比您所要求的要复杂和密集一些,但是拥有一些能够自动捕获调试代码(并以其他方式验证代码的各个组件)的东西可能是“正确”的方法。

我也听说过(但没有做过太多)Class::Inspector这可能适合您的需求。但我认为在相当基本的层面上 - 你想要做的事情不会在编译时进行检查,因为在不实际运行代码的情况下很难评估哪些代码位实际上被调用。因此,您所做的任何事情都必须以某种方式“手动管理”。

停机问题

“在可计算性理论中,停止问题是根据任意计算机程序的描述和输入来确定该程序是否将完成运行或继续永远运行的问题。

艾伦·图灵 (Alan Turing) 在 1936 年证明,解决所有可能的程序输入对的停止问题的通用算法是不存在的。证明的一个关键部分是计算机和程序的数学定义,它被称为图灵机;停机问题在图灵机上是不可判定的。这是决策问题的第一个例子。”

因此,如果您确实想出了一个好的解决方案 - 可能会提供一个有用的大奖:)。