gpt4 book ai didi

perl - 'Goto undefined subroutine &main::1' 编写一个简单的 Perl 调试器

转载 作者:行者123 更新时间:2023-12-02 07:01:17 24 4
gpt4 key购买 nike

我正在尝试编写一个简单的 Perl 调试器,但遇到了以下问题。

我正在运行以下代码作为调试器:

{
package DB;

sub DB { }

sub sub
{
&$sub;

# this is what produces the problem
$i = 1*1;
}
}

1;

我通过设置 PERL5DB 环境变量加载它 - 例如:

export PERL5DB="BEGIN { require './debugger/tracer.pl'; }

给定这个简单的小 Perl 脚本:

#!/usr/bin/env perl

use Getopt::Long;

print "hello world";

我正在运行脚本:

perl -d test.pl

运行时,会产生以下错误:

$ perl -d test.pl
Goto undefined subroutine &main::1 at /home/vagrant/perl5/perlbrew/perls/perl-5.16.0/lib/site_perl/5.16.0/Exporter.pm line 25.
BEGIN failed--compilation aborted at test.pl line 6.

我已将问题隔离到调试器中 &$sub; 调用 sub 之后运行的所有内容。基本 Perl 脚本中包含某些包时会出现此问题 - 在本例中为 Getopt::Long,但我也发现 IO::File 的结果相同。

我的 Perl 很生疏,尤其是在调试器等高级主题方面。

任何人都可以帮助我了解如何在调试器中调用 sub 之后执行代码以与我正在导入的包很好地放置在一起吗?

谢谢!

最佳答案

当您离开 Perl 子例程而不使用显式 return 语句时,Perl 将返回子例程中最后一条语句的值。

特别是,这意味着如果您有一个调用另一个子例程作为其最后语句的子例程,如下所示:

package DB {
sub sub {
warn "Hello from DB::sub, about to call $sub\n";
&$sub;
}
}

然后通过 &$sub 调用的另一个子例程的返回值将被传递给原始调用者,就像您完成了显式的 return &$sub.

但是,如果 &$sub 调用不是 DB::sub 子例程中的最后一件事,那么 Perl 只会抛出去掉它的返回值,而是返回实际最后一条语句的值——在本例中为 $i = 1*1,它的计算结果为数字 1。

现在,当你define a custom debugger像那样,Perl 会将每个 普通子例程调用包装为对您的DB::sub 子例程的调用。因此,您的代码会导致每个 子例程调用返回数字 1!毫不奇怪,这会非常严重地破坏很多东西。

具体来说,根据您的错误消息,它看起来像是 Exporter 中的内容模块(许多其他模块使用它来将符号导出到调用者的命名空间)正在调用一个子例程,该子例程应该返回对另一个子例程的引用。但是,因为你的调试器,它实际上返回 1,下面调用返回的子例程的尝试最终会尝试调​​用名为 1 的子例程(它被映射到 main:: package because numeric symbol names are superglobal ),然后失败。


但如果您真的需要在您的 DB::sub 调用 &$sub 中做一些事情怎么办>?那么,解决方法是保存返回值,如下所示:

package DB {
sub DB { }
sub sub {
warn "Hello from DB::sub, about to call $sub...\n";

# call &sub, save the return value in @rv
my @rv = (wantarray ? &$sub : scalar &$sub);

warn "Hello again from DB::sub, just called $sub and got @rv!\n";

# ...and return the saved return value
return (wantarray ? @rv : $rv[0]);
}
}

1;

(由于我们的 DB::sub 可能会在列表或标量上下文中调用,因此代码稍微复杂一些,我们需要将适当的上下文传递给 &$ sub。不过 wantarray 应该会处理这个问题。)

关于perl - 'Goto undefined subroutine &main::1' 编写一个简单的 Perl 调试器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20255140/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com