【问题标题】:unable to find the function definition in a perl codebase无法在 perl 代码库中找到函数定义
【发布时间】:2023-04-09 17:21:01
【问题描述】:

我正在翻阅 7900 多行 perl 代码。我需要改变一些东西,而且事情进展得很好,即使我只用了 36 个小时进入 perl。我学习了该语言的基本结构,并且能够完成一些小事。但是突然间我发现了一个在任何地方都没有任何定义的函数调用。我多次检查所有“子”。我找不到函数定义。我错过了什么?这个函数的定义在哪里。我很确定这是一个用户定义的函数,而不是一个库函数(从它的名字我猜到了这个)。 请帮我找到这个函数的定义。

这里有几行来自函数用法。

(cfg_machine_isActive($ep)) {
         staf_var_set($ep, VAR_PHASE, PHASE_PREP);
         staf_var_set($ep, VAR_PREP,  STATE_RUNNING);
      } else {
         cfg_machine_set_state($ep, STATE_FAILED);
      }
   }
   $rc = rvt_deploy_library();       #this is the function that is the problem 
   dump_states() unless ($rc != 0);

答案如下:

(由于我没有足够的声誉,我无法发布这个答案本身)

我发现在 perl 中查找导入函数定义的最快方法是以下命令:

>perl.exe -d <filename>.pl

这将启动调试器。 然后;做

b <name of the function/subroutine who's definition you are looking for>

在我们的例子中,这意味着输入:

b rvt_deploy_library

接下来按“c”跳转到提到的函数/子程序。

这会将调试器带到所需的功能。现在,您可以看到行号。以及控制台上函数/子例程的位置。

main::rvt_deploy_library(D:/CAT/rvt/lib/rvt.pm:60): 

【问题讨论】:

  • 请添加更多上下文,比如一个 grep,在神秘的函数用法周围有 10 行上下文。
  • @RC 我已经按照你的建议更新了问题
  • 我会 grep 函数名的代码库。
  • 我知道先生,但那没用!我找不到它!事实上,我什至分别查找了所有出现的“rvt”、“部署”和“库”……仍然没有。现在我相当确信该函数没有在那里定义..我正在寻找程序员可以做到这一点的方法..我的意思是她如何才能“隐藏”定义..

标签: perl


【解决方案1】:

在 Perl 中有多种方法可以声明方法。这是一个几乎可以肯定不完整的列表:

  1. 标准方式,例如。 sub NAME { ... }
  2. 使用 MooseX::Method::Signatures,method NAME (...) {...}
  3. 分配给 typeglob,例如。 *NAME = sub {...};

另外,如果包声明了AUTOLOAD函数,那么可能没有明确的方法定义。请参阅perlsub 了解更多信息。

【讨论】:

  • 您会看到在同一个代码库中定义了其他函数......并且它们都使用 sub。我也想问你,现在我已经用一些代码更新了这个问题,你还有什么想法吗?
  • 检查由该文件导入的所有模块中的 AUTOLOAD 方法。
  • 以及如何检查/查找该文件导入的所有模块? perl 中有 import 语句吗?
  • 搜索use XXX;require XXX;形式的行
  • 哦,是的,先生.. 我已经在使用它了.. 我还使用 -w(开关)和 -d(调试器)命令选项来解决我的问题。
【解决方案2】:

您可以使用B 模块检查任何 perl 值。在这种情况下:

sub function_to_find {}

sub find_sub (\&) {
    my $code = shift;
    require B;
    my $obj = B::svref_2object($code);  # create a B::CV object from $code

    print "$code:\n";

    print "  $$_[0]: $$_[1]\n" for
        [file    => $obj->FILE],
        [line    => $obj->GV->LINE],
        [name    => $obj->GV->NAME],
        [package => $obj->STASH->NAME];
}

find_sub &function_to_find;

打印类似:

CODE(0x80ff50):
  file: so.pl
  line: 7
  name: function_to_find
  package: main

【讨论】:

    【解决方案3】:

    B::Xref 将显示在您的代码使用的所有文件中声明的所有函数。

    【讨论】:

    • 不知道 B::Xref - 很好!
    猜你喜欢
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    • 2022-10-06
    • 2019-12-31
    相关资源
    最近更新 更多