4

perlを使用use strictすると、安全でない構造でランタイムエラーが発生します。ランタイムエラーを発生させるのではなく、警告のみを出力させることができるかどうか疑問に思っていますか?またはuse warnings(または-w)同じ問題について警告していますか?

4

5 に答える 5

14

いいえ、use strict死ぬのではなく警告を発するようにすることはできません。それが行うのは、魔法の$^H変数に数ビットを設定することだけです。これは、Perlインタープリターの内臓でさまざまなことをトリガーします。

いいえ、あなたを殺すuse warningsのと同じことについて警告していません。use strictたとえば、use warnings一度だけ使用される変数について警告します(タイプミスの結果である可能性があります)。

于 2011-03-25T10:42:20.823 に答える
4

ここで本当の動機を推測することに挑戦します。推測が間違っていたら、遠慮なく教えてください。

大規模で古いコードベースに取り組み、制限を有効にしたいと考えていますが、機能を損なうことなく、エラーがどこにあるのか(そしてエラーがいくつあるのか)を最初に把握したいと考えていました。残念ながら、use strictperlパーサーとインタープリターの内部動作を変更することによって機能するため、「緩い厳密」、またはhtmlと同様に、あらゆる種類の「遷移」モードはありません。

use strictただし、正しい方向に動き始めるための機能を切り離すことができます。まず、実際には3つの別々の部分があることに注意してください。

use strict 'refs'; # no symbolic references
use strict 'vars'; # must declare variables
use strict 'subs'; # no barewords

そして、それらのうち「refs」のみがランタイムエラーを生成します。use strict qw(vars subs)したがって、各ファイル(スクリプトとモジュール)に簡単に追加して、でテストすることができますperl -c。エラーメッセージが表示された場合はuse strict、、、または少なくとも2つのチェックのいずれかが失敗した方をコメントアウトし、失敗の性質に関するコメントを追加して次に進みます。このようにして、(ファイルの数に応じて)コンパイル時エラーが発生したファイルをすばやく特定し、後でそれらに対処するために戻ることができます。(現時点で私よりもやる気があれば、このプロセスを自動化することもできます)。ブロック内で恐ろしいことを行うコードがない限りBEGIN、これはかなり安全です。

トリッキーな部分は、によって生成されたランタイムエラーをチェックすることですがuse strict 'refs'、残念ながら、これを行う簡単な方法はありません。エラーは、静的分析では判別できないシンボリック参照によってトリガーされるため、-cおよび/またはPerl::Criticはどちらも役に立たない。

うまくいけば、それはあなたの本当の問題に取り組むことに近づくでしょう。

于 2011-03-29T04:13:54.477 に答える
4

warningsとプラグマは補完的であり、strict重複していません。strictプラグマには、コンパイル時と実行時の両方の効果があります。制限の重大度をエラーから警告に下げることはできませんが、完全に無効にすることはできます。たとえば、独自のエクスポートルーチンを作成している場合は、シンボルテーブルを操作するためにシンボリック参照を有効にする必要があります。

{
    no strict 'refs';
    # symrefs okay within this block
}

警告は字句的に無効にすることもできます(use warningsほとんど廃止された-wフラグの代わりに無効にしたと仮定します)。

狭窄と警告はセーフティネットを提供します。そのため、デフォルトで使用することをお勧めします。それらを無効にする場合は、必要なものだけを無効にし、変更を可能な限り最小のスコープに制限する必要があります。

于 2011-03-25T15:19:04.167 に答える
3

推奨される方法:

use Carp;

sub foo {
  croak "no args" unless @_;
}

eval foo();
if( $@ ){
  print "caught die: $@";
}

die'を'に変更できない場合croak

sub foo {
  die "no args" unless @_;
}

{
  my $prev_die = $SIG{__DIE__};
  $SIG{__DIE__} = sub { print "caught die: $_[0]"; };
  eval foo();
  $SIG{__DIE__} = $prev_die;
}

2番目の方法は、STDERRのエラーを出力します。

見る:

perldoc -f eval

perldoc perlvarとを検索し/\$\@/ます/__DIE__/

perldoc Carp

于 2011-03-25T14:17:39.663 に答える
1

警告は致命的にすることができます— perllexwarnを参照してください—しかし、厳密なエラーを致命的でないものにすることはできません。

なぜあなたはそれをしたいのですか?XY問題が疑われます。

于 2011-03-25T19:48:19.657 に答える