In the POD for Test::Base, there is an example on rolling my own filters, which the documentation says is “self explanatory”. I am having trouble understanding it and I think it may be a problem in my filter writing. The code is reproduced below:
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;
}
The filters function sets the named subroutines as filters on the incoming data. The declared filters are ‘foo’ and ‘bar’, which has arguments.
My question is why the structure of foo and bar are so different. Why is foo in the current namespace while bar is declared in the Test::Base::Filter namespace? And why does foo alter its first argument, while bar must grab the data from the second argument?
Another example. In 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];
}
And in test.t:
use t::MyTest;
filters {input => [qw(choose is_defined)] };
__END__
=== First
--- input
1
--- expected: 1
=== Second
--- input
0
--- expected: 0
If you place both of those in a “t” folder and run prove -v, this is the output:
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
Nevermind the warning (which I don’t completely understand the root of). Why is the first filter passed the input (like it’s supposed to be), but the second one is passed some Filter object? Shouldn’t the input of the second filter be the output of the first? If it isn’t, then I have to worry about filter ordering all over the place.
I figured this out. I’m pretty sure it’s a bug in the way filters work.
The POD says:
Perldoc tells me that
undefis a valid scalar in Perl, but Test::Base::Filter ignores it. Normally the input to a Filter would be first the data, and then some other stuff. However, if a filter returns undef, then its return value is ignored and the next filter gets one less argument, instead of gettingundefas its first argument. I’ll file this in RT.