Skip Menu |

This queue is for tickets about the Filter-Simple CPAN distribution.

Report information
The Basics
Id: 28986
Status: new
Priority: 0/
Queue: Filter-Simple

People
Owner: Nobody in particular
Requestors: atara-y [...] mx.scn.tv
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.82
Fixed in: (no value)



Subject: terminator given by hash reference has no effect
If the second argument of FILTER is a reference to a hash and the hash has a value associated with key 'terminator', the terminator is not actually used as terminator. This is because "%terminator" is given to filter closure and values in the hash reference is not copied to the "%termianator". The easiest way to fix it is to copy the values in the hash reference to copy "%terminator". However, attached patch employs another approach. The given hash reference is passed through to filter closure. This gives possibility to modify "becomes" value in filter function or terminator regexp (in this case, via (?{code}) construct). In addition, "becomes" in terminator hash reference is not mentioned in the current documentation. I try to descibe it in the attached patch, accoding to my understandings.
Subject: Filter-Simple-0.82.patch
--- /usr/lib/perl5/5.8/Filter/Simple.pm 2005-06-27 11:31:44.000000000 +0900 +++ Filter/Simple.pm 2007-08-26 02:45:08.021129600 +0900 @@ -160,24 +160,27 @@ my $ows = qr/(?:[ \t]+|#[^\n]*)*/; sub gen_filter_import { - my ($class, $filter, $terminator) = @_; - my %terminator; + my ($class, $filter, $terminator_) = @_; + my $terminator; my $prev_import = *{$class."::import"}{CODE}; return sub { my ($imported_class, @args) = @_; my $def_terminator = qr/^(?:\s*no\s+$imported_class\s*;$ows|__(?:END|DATA)__)\r?$/; - if (!defined $terminator) { - $terminator{terminator} = $def_terminator; + if (!defined $terminator_) { + $terminator->{terminator} = $def_terminator; } - elsif (!ref $terminator || ref $terminator eq 'Regexp') { - $terminator{terminator} = $terminator; + elsif (!ref $terminator_ || ref $terminator_ eq 'Regexp') { + $terminator->{terminator} = $terminator_; } - elsif (ref $terminator ne 'HASH') { + elsif (ref $terminator_ ne 'HASH') { croak "Terminator must be specified as scalar or hash ref" } - elsif (!exists $terminator->{terminator}) { - $terminator{terminator} = $def_terminator; + else { + if (!exists $terminator_->{terminator}) { + $terminator_->{terminator} = $def_terminator; + } + $terminator = $terminator_; } filter_add( sub { @@ -186,8 +189,8 @@ my $data = ""; while ($status = filter_read()) { return $status if $status < 0; - if ($terminator{terminator} && - m/$terminator{terminator}/) { + if ($terminator->{terminator} && + m/$terminator->{terminator}/) { $lastline = $_; last; } @@ -199,8 +202,8 @@ $_ = $data; $filter->($imported_class, @args) unless $status < 0; if (defined $lastline) { - if (defined $terminator{becomes}) { - $_ .= $terminator{becomes}; + if (defined $terminator->{becomes}) { + $_ .= $terminator->{becomes}; } elsif ($lastline =~ $def_terminator) { $_ .= $lastline; @@ -429,6 +432,13 @@ (in which case the terminator is the value associated with the key C<'terminator'>. +If you need to terminate filtering, you need to ensure that filtered result +ends by C<no ModuleName;> or a line including the same effect. Otherwise, +applying filter continues beyond the terminator line!! If the second argument +is a reference to a hash, it can be achieved by setting the value associated +with the key C<'becomes'>. A line including terminator is replaced with the +value associated with the key C<'becomes'>. + For example, to cause the previous filter to filter only up to a line of the form: @@ -441,6 +451,7 @@ FILTER { s/BANG\s+BANG/die 'BANG' if \$BANG/g; + $_ .= "no BANG;\n"; # to ensure filter ends } qr/^\s*GNAB\s+esu\s*;\s*?$/; @@ -448,9 +459,19 @@ FILTER { s/BANG\s+BANG/die 'BANG' if \$BANG/g; + $_ .= "no BANG;\n"; # to ensure filter ends } { terminator => qr/^\s*GNAB\s+esu\s*;\s*?$/ }; +or: + + FILTER { + s/BANG\s+BANG/die 'BANG' if \$BANG/g; + } + { terminator => qr/^\s*GNAB\s+esu\s*;\s*?$/, + becomes => "no BANG\n"; # to ensure filter ends + }; + and to prevent the filter's being turned off in any way: package BANG;