2

Test::BaseのPODには、独自のフィルターをロールする例があり、ドキュメントには「自明」と書かれています。私はそれを理解するのに苦労しており、私のフィルターの書き方に問題があるのではないかと思います。コードを以下に再掲します。

use Test::Base;

filters 'foo', 'bar=xyz';

sub foo {
    transform(shift);
}

sub Test::Base::Filter::bar {
    my $self = shift;       # The Test::Base::Filter object
    my $data = shift;
    my $args = $self->current_arguments;
    my $current_block_object = $self->block;
    # transform $data in a barish manner
    return $data;
}

このfilters関数は、指定されたサブルーチンを着信データのフィルターとして設定します。宣言されたフィルターは、引数を持つ「foo」と「bar」です。

私の質問は、なぜ foo と bar の構造がそれほど異なるのかということです。Test::Base::Filter 名前空間で bar が宣言されているのに、なぜ foo が現在の名前空間にあるのですか? また、foo は最初の引数を変更するのに、bar は 2 番目の引数からデータを取得する必要があるのはなぜでしょうか?

もう一つの例。MyTest.pm で:

package t::MyTest;
use Test::Base -Base;
#some stuff here

package t::MyTest::Filter;
use base 'Test::Base::Filter';

sub choose {
    print @_;
    return {foo => 'bar'} if($_[0] eq '1');
    return undef;
}
sub is_defined{ 
    print @_;
    defined $_[0];
}

そしてtest.tで:

use t::MyTest;

filters {input => [qw(choose is_defined)] };
__END__
=== First
--- input
1
--- expected: 1
=== Second
--- input
0
--- expected: 0

それらの両方を「t」フォルダーに入れて実行するprove -vと、次の出力が得られます。

t\01-test.t .. Use of uninitialized value $_[1] in print at t/MyTest.pm line 14,
 <DATA> line 1.

1
t::MyTest::Filter=HASH(0x2af1670)ok 1 - First
1..1
Failed 1/1 subtests

Test Summary Report
-------------------
t\01-test.t (Wstat: 0 Tests: 0 Failed: 0)
  Parse errors: Bad plan.  You planned 1 tests but ran 0.
Files=1, Tests=0,  1 wallclock secs ( 0.06 usr +  0.23 sys =  0.30 CPU)
Result: FAIL

警告を気にしないでください (私はその根源を完全には理解していません)。最初のフィルターが入力を渡されたのはなぜですか? 2 番目のフィルターの入力を最初のフィルターの出力にするべきではありませんか? そうでない場合は、あらゆる場所でフィルターの順序を気にする必要があります。

4

1 に答える 1

0

私はこれを理解しました。フィルタの動作のバグだと確信しています。PODは言う:

Each filter can take either a scalar or a list as input, and will return either a scalar or a list. Since filters are chained together, it is important to learn which filters expect which kind of input and return which kind of output.

Perldocはundef、それがPerlで有効なスカラーであると教えてくれますが、Test :: Base::Filterはそれを無視します。通常、フィルターへの入力は最初にデータであり、次に他のデータです。ただし、フィルターがundefを返す場合、その戻り値は無視され、次のフィルターは最初の引数として取得するのではなく、1つ少ない引数を取得undefします。これをRTで提出します。

于 2012-09-22T21:18:26.760 に答える