CORE Perl中的哪些东西设置了成功的错误号($!)?
根据,可以打开标量的文件句柄CORE Perl中的哪些东西设置了成功的错误号($!)?,perl,error-handling,Perl,Error Handling,根据,可以打开标量的文件句柄 open my $fh, ">", \$scalar or die; 为什么$在使用此选项时设置 use strict; use warnings; use autodie; use Test::More tests => 3; is ( $!, '', '$! is not set' ); my $output; open ( my $fh, '>', \$output ); print $fh "Hello, World!"; is
open my $fh, ">", \$scalar or die;
为什么$代码>在使用此选项时设置
use strict;
use warnings;
use autodie;
use Test::More tests => 3;
is ( $!, '', '$! is not set' );
my $output;
open ( my $fh, '>', \$output );
print $fh "Hello, World!";
is ( $output, "Hello, World!", "Got the right output" );
is ( $!, '', '$! is not set' );
这真的很奇怪:fork
返回pid
,因此您可以通过查看$来确定失败代码>。我想,<代码>$代码>仅在失败时设置。文档明确指出,成功时不会清除此变量
如果失败,许多系统或库调用将设置为errno,以指示失败的原因如果成功,它们通常不会将errno
设置为零。这意味着errno
,因此$代码>,仅在发生故障后立即有效-perldoc perlvar
因此,通常您必须清除$代码>发生故障后。但我们是否也应该在成功后清除它?设置了哪些内容$代码>成功?答案重写
我在问题中说,
这真的很奇怪:fork
返回pid,因此您可以通过查看$来确定失败代码>
这不是真的:fork
通过返回pid的undef
指示失败。从perldoc-f fork
它将子pid返回到父进程,将0返回到子进程,如果fork失败,则返回undef
从中,您可以看到:
有些情况下,您必须事先清除它,因为没有提供其他机制来指示错误-grinz
但是,fork
似乎不属于这种情况。因此,似乎任何东西都可以将任何东西放入$中代码>。也就是说,即使没有发生错误,$代码>可以填充。但仅当您依赖$时对于存在的错误,您应该事先清除它,并且永远不要依赖$除非需要,否则代码>用于错误状态
怎么会呢!当你使用这个的时候会被设置吗
$代码>始终由成功调用设置。这就是为什么$代码>仅在函数指示$时才有意义代码>有意义(通过返回错误)
这里打开了Perl上的原始bug
不是Perl中的bug。根据您引用的文档,$
仅在调用失败后才有意义,因此在成功调用后为其值赋值是代码中的一个错误
因此,通常您必须清除$代码>发生故障后
您永远不需要清除$代码>
这真的很奇怪:fork
返回pid,因此您可以通过查看$来确定失败代码>
否,返回错误时的undef
。只勾选$
iffork
返回undef
my $pid = fork();
defined($pid)
or die($!);
if (!$pid) {
my $rv;
if (!eval { $rv = child(); 1 }) {
# Let's be careful in case the stringification of $@ fails.
my $e = $@;
eval { warn($e); 1 }
or warn("Unknown error");
# Attempt to return something meaningful like Perl does.
exit( $! || ($? >> 8) || 255 );
}
exit($rv);
}
waitpid($pid, 0);
嗯,“与$!和$^E相反,它们只有在检测到错误条件时才设置,……”这确实表明我的第一条评论是错误的:|“因此,通常在出现故障后,您必须清除$!
”“不,您不必清除$!”代码>。您应该只查看$代码>故障后;试图让它保持一种可靠的状态,你可以随时检查它,这不是你想走的路。你永远不必清除$代码>系统调用之前除外,该系统调用没有其他错误指示,如getpwent
和friends。它可能是由一个系统调用设置的,该系统调用作为打开进程的一部分运行,其失败只是分支逻辑的一部分代码>用于系统调用错误,这是一个特定的unixy事件;它本身不是Perl高级错误机制,它可能由系统调用设置,这些调用可能与您尝试执行的操作直接相关,也可能与您尝试执行的操作无关<当发生导致操作失败的系统调用错误时,code>open
仅返回false,并且依赖于$代码>已正确设置。“您永远不需要清除$!”。当您从getpwent
检测到错误时,您的意思是什么?getpwent
和类似的情况是一种特殊情况(当然,不是唯一的情况),因为系统调用本身设计得很糟糕。请参阅Perl的getpwent
不保证返回到$代码>在成功时保持不变,因此文档中描述的C调用方法对于Perl的调用是不可靠的。这将由Perl自己来完成errno=ENOERROR代码>并在返回时检查errno
。它似乎就是这样做的。Perl的getpwent
文档说它在出错时返回一个无意义的真值。因此,正确的调用方法(如果您想检查错误)是使用,而(1){my$count=my$name=getpwent();$count!=1或die($!);last if!$count;…}
@grinzit说如果条目不存在,它将返回一个无意义的真值,这与诸如getpwnam
之类的函数相关,并且在使用迭代getpwent
/getgrent
函数时不会发生,因为这些函数不寻找特定的条目。(文件可能需要澄清)