Perl 子程序如何报告调用它的行?

How can a Perl subroutine report the line that called it?

提问人:terdon 提问时间:3/23/2017 更新时间:3/23/2017 访问量:465

问:

我正在编写一个 Perl 管道,一个调用各种其他程序并管理从一个程序传递到另一个程序的数据的脚本。脚本(称为 )和它管理的各种子脚本都共享一个常见子程序列表,这些子程序定义并通过指令包含在指令中。pipeline.plsubroutines.phrequire subroutines.ph

其中一个函数的工作是退出打印错误消息(实际的子例程也做一些其他工作,但它们在这里无关紧要;不,我不是在重新发明):die()

## subroutines.ph
sub errorDie
{
    my ($errMsg) = @_;
    ## various other cleanup tasks here
    die($errMsg);
}
1;

而且,在:pipeline.pl

#!/usr/bin/perl 
require 'subroutines.ph';

errorDie("foo")

运行上述脚本会导致:

foo at subroutines.ph line 5.

是否可以让它报告如下内容:

foo at pipelines.pl line 4.

因此,它应该报告从中调用子例程的原始脚本的行,而不是报告找到子例程的行。我知道我可以通过在变量中包含该行来做到这一点,但这很脆弱且繁琐。这可以自动完成吗?外部文件中定义的子例程能否检测从何处调用它?die()errorDie$errMsg

Perl 子程序 错误报告 模具

评论

2赞 Mohit 3/23/2017
你听说过鲤鱼吗?我认为这是您需要使用的。请参阅此链接 - perldoc.perl.org/Carp.html
0赞 terdon 3/23/2017
@Mohit哦,哇。是的,我知道但不知道它会自动这样做。谢谢!carp
1赞 Borodin 3/23/2017
@terdon:差不多就是这样了!
0赞 terdon 3/23/2017
@Borodin没事,揉进去为什么不:P事实上,这几乎就是它所做的一切。出于某种原因,尽管我已经知道它很多年了,但我从未意识到这个非常明显的事实。

答:

7赞 nlu 3/23/2017 #1

有 ,要做到这一点:https://perldoc.perl.org/functions/caller.htmlcaller

my ($package, $filename, $line) = caller;

为您提供所需的信息。

但是,正如您谈论的一般调试一样,您可以从 中获得完整的回溯,如前所述。carp

评论

0赞 terdon 3/23/2017
很抱歉将接受切换到另一个答案,但由于他们提供了一个实际示例,因此最好将该答案放在页面顶部。谢谢!
0赞 cesargastonec 5/5/2018
这足以制作一个带有代码行号的简单日志文件
4赞 ikegami 3/23/2017 #2

这就是鲤鱼的重点.croak

Pkg.pm:

package Pkg;

use Carp qw( croak );

sub some_func {
    my ($cmd, $param) = @_;

    $cmd eq 'encode' || $cmd eq 'decode'
       or croak("Invalid command \"$cmd\"");

    # ...
}

1;

a.pl:

use Pkg;

Pkg::some_func('foo', 'bar');

输出:

Invalid command "foo" at a.pl line 3.