4

アプリに必要な他の構成値を検証するために後で使用されるタイプを定義するために、構成ファイル (YAML) を使用しています。

---
action: >
        use List::MoreUtils;
        my $value = $_;
        any { $value eq $_ } qw(fatal keep merge non-fatal replace);
dir   : return defined $_ ? -d $_ : -1;
file  : return defined $_ ? -f $_ : -1;
string: 1;


---
config-element:
    value: foo
    type : file
etc ...

アイデアは、eval各タイプ定義に対して、それらをハッシュにスローしてから、構成データを検証するために呼び出すことです (以下は、わかりやすくするための概略図です)。

#throw sub refs into hash
my %type_sub;
foreach my $key (keys %$type_def_ref) {
    my $sub_str = "sub {$type_def_ref->{$key}}";
    $type_sub{$key} = eval $sub_str;

}

#validate (myfile is a real file in the cwd)
print $type_sub{file}->('myfile'),"\n";
print $type_sub{action}->('fatal'), "\n";

問題は、%type_sub のサブルーチンがパラメーターを受け入れないように見えることです。上記の場合、最初の print ステートメントは出力-1し、2 番目の出力は次のようになります。

Use of uninitialized value $value in string eq at (eval 15) line 1.
Use of uninitialized value $_ in string eq at (eval 15) line 1.
Can't call method "any" without a package or object reference at 
(eval 15) line 1.

これは私が期待するものではありませんが、サブルーチンが呼び出されています。

私は何を間違っていますか?

編集:私はずさんでしたが、今ではすべて正常に動作しています。フリードのおかげです。

4

2 に答える 2

5

構成にコードを記述しないでください。コードでライブラリを作成し、使用するサブルーチン名を設定するだけです。これにより、文字列をコードに変換し、プロセスを管理するという膨大な量の作業を節約できます。また、誰かが構成を調整して構文エラーを導入したときに、問題を追跡する時間を大幅に節約できます。

これについては、Mastering Perlの「構成」の章と動的サブルーチンの章で詳しく説明しています。

コードが構成に属していません。あなたがそれを信じるまでそれを言ってください。

于 2010-01-19T16:39:56.040 に答える
3

サブルーチンのパラメーターは@_、ではなく配列になります$_。最初のパラメーターを取得するには、検索$_[0]または実行しますmy $foo = shift;。(デフォルトshiftで動作し@_ます。)

についてanyは、実行時にプロトタイプをロードできないことが問題の原因だと思いanyます (サブルーチン プロトタイプはコンパイル時にのみ呼び出すことができます)。明示的な括弧と明示的なサブルーチン参照を使用する必要がある場合があります。

any( sub { $value eq $_ }, qw(fatal keep merge non-fatal replace) );
于 2010-01-19T15:38:19.600 に答える