自定义错误处理捕获通常不显示的错误

Pma*_*oen 2 error-handling perl file stat

我有一个问题,我似乎无法弄明白,我希望你们能帮助我.
问题发生在:

  • 我使用自定义错误处理
  • 我在一个单独的模块中使用File :: Stat

例:

主文件

use strict;
use warnings;

# signal handling
$SIG{__DIE__} = sub {
    my $error = @_;
    chomp $error;
    print "die: $error\n";
};

require mod; 

mod->get_stat();
Run Code Online (Sandbox Code Playgroud)

package mod;

use strict;
use warnings;
use File::stat;

sub get_stat {
    my $file_path = "test.txt";
    my $file_size = stat($file_path)->size;
    print $file_size;
}

1;
Run Code Online (Sandbox Code Playgroud)

这将导致以下输出:

die: 1
die: 1
die: 1
die: 1
die: 1
4
Run Code Online (Sandbox Code Playgroud)

现在,如果我删除我的自定义错误处理或者如果我使用 mod而不是require将不会显示模具.

有趣的是它确实产生了一个结果(test.txt是4个字节),这意味着stat正在按预期工作.

那么,为什么我会收到此错误?这真的是一个错误吗?默认的perl错误处理是否忽略"1"的错误?

编辑
正如Linus Kleen所说,我得到"1"的原因是因为我在显示数组中的元素数量.

如果我打印出错误的内容,我会收到以下错误:

die: Your vendor has not defined Fcntl macro S_ISVTX, used at c:/Perl64/lib/File/stat.pm line 37.

die: Your vendor has not defined Fcntl macro S_IFSOCK, used at c:/Perl64/lib/File/stat.pm line 41.

die: Your vendor has not defined Fcntl macro S_IFBLK, used at c:/Perl64/lib/File/stat.pm line 41.

die: S_IFFIFO is not a valid Fcntl macro at c:/Perl64/lib/File/stat.pm line 41.

die: Your vendor has not defined Fcntl macro S_IFLNK, used at c:/Perl64/lib/File/stat.pm line 41.

4
Run Code Online (Sandbox Code Playgroud)

但仍然,我收到一个错误,没有自定义错误处理,我没有得到.

Lin*_*een 6

将其更改为

my ($error) = @_;
Run Code Online (Sandbox Code Playgroud)

您在代码示例中使用了标量上下文,它将为您提供元素的数量@_,即1.


cjm*_*cjm 6

正如perlvar中所解释的那样,由于实现,$SIG{__DIE__}即使代码在eval中死亡,也会调用钩子.当文件::统计被加载后,它会检查,看看有什么常数FCNTL你的平台上支持.它捕获由不支持的常量引起的错误,但不是在钩子看到它们之前.

你可以eval通过检查你的价值来判断你是否在$^S.如果它不是0,那么你就是eval.

$SIG{__DIE__} = sub {
    return unless defined $^S and $^S == 0; # Ignore errors in eval
    my ($error) = @_;
    chomp $error;
    print "die: $error\n";
};
Run Code Online (Sandbox Code Playgroud)

当您use不是require因为use是编译时操作而且require是运行时操作(因为设置%SIG)时,您没有看到错误.当你use mod和它use的File :: stat时,这一切都发生你设置你的钩子之前.当你require mod,直到你安装了钩子才会发生这种情况.