2

我有一个我似乎无法弄清楚的问题,我希望你们能帮助我。
问题发生在:

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

例子:

主文件

use strict;
use warnings;

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

require mod; 

mod->get_stat();

模块

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;

这将导致以下输出:

die: 1
die: 1
die: 1
die: 1
die: 1
4

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

有趣的是它确实产生了一个结果(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

但是,我仍然收到一个错误,如果没有自定义错误处理,我不会得到。

4

2 回答 2

7

正如perlvar中所解释的,由于实现故障,$SIG{__DIE__}即使代码eval中,也会调用挂钩。加载File::stat时,它会检查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";
};

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

于 2011-11-10T11:18:08.413 回答
6

将其更改为

my ($error) = @_;

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

于 2011-11-10T10:42:26.303 回答