2009-06-25 19 views
6

$に割り当てることはOKですか? Perlのエラー?

例えば、

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

私はトップレベルで、すべてのエラーを処理することができますこの方法。

ありがとうございました。

+1

私はPerlがまったく正当化されたとは思わないと思います...;) –

答えて

12

それがシステム内に配置されますerrno変数は数値だけをとります。

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

と定義されたシステム・エラー番号の文字列値を取得しますが、あなたは、あなたがやりたいことはできません - 任意の文字列に設定する:だから、実際に行うことができます。そのような文字列は、あなたに引数 "..."を与えます。スカラー割り当ての警告では数値ではなく、errnoを0に設定してください。

もう1つの問題は$!システムコールによって変更される可能性があります。だから、それを信じるだけで、あなたが印刷物をするまで、あるいは何か他のことについてあなたが設定する価値を持つことができます。おそらくあなた自身のエラー変数が必要です。

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を使用すると主張します。だから誰かが作ったことは何か間違っている。 –

+0

FYIと同じように、多くの人が図書館内で「死ぬ」という言葉を使っています。 _error/_errorsフラグと適切なアクセサーメソッドを使用します(理想的には、高速の真偽チェックとエラーリストの出力用に1つ)。好ましくは、オブジェクトレベルでこれを作ってください:) – DVK

+0

@DVK私は強く反対します。ライブラリが例外をスローするのに適しています。まあまあ例外的です。あなたがエラーを処理する方法と、それについて一貫していることをドキュメントします。どうして?ライブラリのユーザーは、エラーが発生したときを知りたいと思うでしょう。ほとんどの場合、彼らは単に死んでしまうことがあります。これはどこにでも "$ obj-> method"や "$ obj-> error"と書くことにつながります。あなたは怠け者になり、忘れてしまい、間違いがあります。例外は、エラーから回復したい場所に特別なコードを追加するだけでよいことを意味します。 autodieをしばらく使用すると、表示されます。 – Schwern

3

私のラビは「いいえ!

+7

私はこれを投票するように誘惑されていますが、それは実際に正直であるので、答えは投票に間違っています:-)。ここのレッスンは、彼がPerlを知っていない限り、これについてのRabbiを信頼しないことです。 –

+2

ユーモアで私のラメの試みを見てくれてありがとう!ラビとコーシャーの厳密な定義によれば、$!ユダヤ教の特定の法律によってカバーされていないので、それは "コーシャー"ではありません。しかし、あなたが異邦人のために許されるかもしれません。 – CoderDennis

+1

私は誰かが質問のタイトルを編集することを期待しているので、元のタイトルが「Perlで$!に割り当てることは正当なものか」ということを先取りして指摘しています。 – ysth

3

$!が細かい設定が、:

  • あなたの機能
  • の最後にそれを行う必要がありますが、エラーが発生したことを示す別の値を返す必要があります
  • 、あなたのOSを使用する必要があります
  • 設定目的の文字列ではなく、errnoの値
  • チェックコードは、関数の失敗時(および関数によってエラーが示された場合のみ)に値をチェックする必要があります。

何かを念頭に置くと、dieは$!の値を使用します。その終了コード(ゼロでない限り)。

0

エラーを格納する変数が1つしかない場合は、エラー変数の状態を確認する前にプログラムに複数のエラーが発生していると問題が発生します。あなたがそれを助けることができれば、それは避ける価値があります。

ありがとうございますが、あなたはそれを助けることができます。本当に素晴らしい解決策は、Error.pmからのオブジェクト指向例外処理を使用することです。

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記事もあります:このモジュールは、あなたがこのようにtry/catchブロックを記述することができます。

+0

私は例外を2番目に使用しますが、エラーは使用しません。 [Exception :: Class](http://search.cpan.org/dist/Exception-Class/lib/Exception/Class.pm)を代わりに使用すると、はるかに優れています。 – jplindstrom

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モジュールがあります。

関連する問題