想象一下,我有这个简单的功能
say_hi() || die "ERROR: sub say_hi had an issue: Details => $!\n";
sub say_hi{
my ($name) = @_;
return unless $name;
print "Hi $name\n";
return 1;
}
如何在sub中设置 $!的内容,以便在函数返回后使用它。我正在尝试做类似于
的事情open() || die "$!";
一样。谢谢
答案 0 :(得分:3)
perldoc -v $!
:
引用时,
$!
检索C“errno
”的 当前值 整数变量 。如果为$!
分配了一个数值,那么该值 存储在“errno”中。当引用为字符串时,$!
会产生 系统错误字符串对应于“errno
”。...对
$!
的分配同样是 短暂的 。它 可以在调用“die()
”运算符之前立即使用 设置退出值,或检查系统错误字符串 对应于错误n
,或将$!
恢复为有意义的状态。 (强调我的)
这就解释了为什么你不能做到这一点:
#!/usr/bin/env perl
say_hi() or die "ERROR: sub say_hi had an issue: Details => $!\n";
sub say_hi{
my ($name) = @_;
unless ($name) {
$! = 'no name';
return;
}
print "Hi $name\n";
return 1;
}
结果是:
ERROR: sub say_hi had an issue: Details =>
考虑使用eval
/ $@
:
#!/usr/bin/env perl
eval { say_hi() } or die "ERROR: sub say_hi had an issue: Details => $@\n";
sub say_hi{
my ($name) = @_;
$name or die "no name\n";
print "Hi $name\n";
return 1;
}
另请参阅“Is Try::Tiny still recommended for exception handling in Perl 5.14 or later?”
如果你在这个问题的答案中遵循brian的建议,你可以做类似的事情:
#!/usr/bin/env perl
use strict;
use warnings;
my $r = say_hi();
$r->{success}
or die sprintf "ERROR: sub say_hi had an issue: Details => %s\n", $r->{reason};
sub say_hi{
my ($name) = @_;
$name or return { success => 0, reason => 'Missing "name"' };
print "Hi $name\n";
return { success => 1 };
}
或者,您可以使用Params::Validate或Validate::Tiny等
答案 1 :(得分:3)
$!
是C&#39 {s} errno
的代理。值errno
可以在Errno中作为常量使用。
use Errno qw( EINVAL );
sub foo {
my ($arg) = @_;
if (!$arg) {
$! = EINVAL;
return 0;
}
...
return 1;
}
foo(...)
or die($!);
很少这样做,主要是因为您仅限于为系统调用设计的错误代码。抛出异常或具有特定于模块的错误变量(例如$DBI::err
)更为常见。