Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CORE Perl中的哪些东西设置了成功的错误号($!)?_Perl_Error Handling - Fatal编程技术网

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
。只勾选
$
if
fork
返回
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
函数时不会发生,因为这些函数不寻找特定的条目。(文件可能需要澄清)