2009-06-25 62 views
6

可以分配给$!在Perl中的错误?

例如,

if(! (-e $inputfile)) 
{ 
     $! = "Input file $inputfile appears to be non-existent\n"; 
     return undef; 
} 

这样我可以在顶级处理所有的错误。

谢谢。

+1

我不认为Perl会被认为是犹太教...;) – 2009-06-25 18:43:47

回答

12

如果分配到$ !,它被放置在系统errno变量,只需要数字。所以,你其实可以做的事:

use Errno "EEXIST"; 
$! = EEXIST; 
print $!; 

,并获得一个定义的系统错误号的字符串值,但你想要的东西,你不能这样做 - 将其设置为任意字符串。这样的字符串会给你一个参数“...”在标量赋值警告中不是数值,并将errno设置为0.

另一个问题是$!可能会被任何系统调用改变。所以你只能相信它有你设置的价值,直到你做一个印刷或其他任何东西。你可能需要你自己的错误变量。

2

是的,你可以分配东西(#)到$!,只是要警惕你做的地方,所以你不要搞乱一些其他功能的消息。

9

那么,documentation说,这基本上是一个系统错误的指标。所以我不会分配它,你只是让你的lib的用户发疯。

使用异常,而不是:

eval { # this ain't the evil eval 
    # some code 
    die $something; 
} 
if (my $err = [email protected]) { 
    # exception handling 
} 

注意,您可以“抛”,或死亡,大约有您需要什么..

+0

$中的值!不保证是任何东西,除非在函数调用之后立即检查。失败和b。声称使用errno。所以任何被造的人都会做错事。 – 2009-06-25 18:13:26

+0

就像一个供参考,许多人认为使用图书馆“死”非常treif(又名非犹太教:)的东西。 使用_error/_errors标志和适当的访问器方法(理想情况下,一个用于快速真/假检查,另一个用于打印错误列表)。最好在物件层面上做到这一点:) – DVK 2009-06-26 12:51:27

+0

@DVK我强烈反对。它更适合图书馆抛出异常,只要它们真的非常特殊,并且你记录了你将如何处理错误并保持一致。为什么?图书馆的用户将想知道何时出现错误。如果有的话,他们通常会死亡。这导致在任何地方编写“$ obj->方法或死于$ obj->错误”。你会很懒,忘记和错过一个错误。例外情况意味着您只需在要从错误中恢复的地方添加特殊代码即可。使用autodie一段时间,你会看到。 – Schwern 2009-06-27 18:38:48

3

设置$!是好的,但:

  • 你应该在你的函数
  • 结束做到这一点,你应该返回不同的值都表示出现了错误
  • 你应该用你的操作系统的errno值而不是字符串用于设置
  • 检查代码需要检查该值是否应该立即在功能失败时立即执行(并且只有在功能指示失败时)

需要记住的是die使用$!中的值为它的退出代码(只要它不是零)。

0

如果您只有一个变量来存储错误,那么在检查错误变量的状态之前,如果在程序中发生了多个错误,则会出现问题。如果你能帮上忙,那就值得避免。

谢谢你在Perl中可以帮到你。一个非常好的解决方案是使用来自Error.pm的面向对象的异常处理。此模块将允许你写try/catch块,像这样:

try { 
    some code; 
    code that might thrown an exception; 
    more code; 
    return; 
} 
catch Error with { 
    my $ex = shift; # Get hold of the exception object 
    # handle the exception; 
}; 

CPAN documentation该模块是相当不错的,并有一个Perl.com文章的主题了。

0

$!有很多警告,作为一个全局变量,有很多函数会分配给它(其中一些是Perl调用的C函数),我会简单地抛出一个异常(在Perl中意味着死亡),并让用户捕获它。因此,而不是写:

$obj->foo or die $!; 
$obj->bar or die $!; 
$obj->baz or die $!; 

甚至

$obj->foo or die $obj->error; 
$obj->bar or die $obj->error; 
$obj->baz or die $obj->error; 

,你可以只写

$obj->foo; 
$obj->bar; 
$obj->baz; 

,并知道如果有你的它被告知一个错误。此外,你上面的任何人都将被告知并可以将其捕获。因为这是最常见的情况,所以用户不需要记住它并一遍又一遍地输入。

如果您想忽略或从错误中恢复,只需使用eval BLOCK即可。

eval { $obj->foo }; # don't care if it works or not 
eval { $obj->bar } or do { ...something when it doesn't work... }; 

由于这是它应该是用户必须记住添加更多的代码,并做更多的工作的例外情况。

此方法的示例包括DBI's RaiseError flag,它仅在默认情况下为关闭状态而关闭,以及美妙的autodie模块。

相关问题