Text-OutputFilter
view release on metacpan or search on metacpan
OutputFilter.pm view on Meta::CPAN
my $fh;
if (ref $io eq "GLOB" and ref *{$io}{IO} eq "IO::Handle") {
open $fh, ">&", *{$io}{IO};
}
elsif (ref $io eq "SCALAR") {
open $fh, ">", $io;
}
else {
eval { $fno = fileno $io };
defined $fno && $fno >= 0 or
croak "OutputFilter tie's 2nd arg must be the output handle\n";
open $fh, ">&", $fno;
}
$fh or croak "OutputFilter cannot dup the output handle: $!";
select ((select ($fh), $| = 1)[0]);
bless {
pfx => " " x $lm,
sb => $ref,
io => $fh,
line => "",
closed => 0,
}, $class;
} # TIEHANDLE
sub BINMODE {
my $self = shift;
$self->{closed} and croak "Cannot set binmode on closed filehandle";
if (@_) {
my $mode = shift;
binmode $self->{io}, $mode;
}
else {
binmode $self->{io};
}
} # BINMODE
sub FILENO {
my $self = shift;
fileno $self->{io};
} # FILENO
sub _Filter_ {
my ($nl, $pfx, $sub, $line) = @_;
my $l = $sub->($line);
defined $l ? $pfx . $l . ($nl ? "\n" : "") : "";
} # _Filter_
sub PRINT {
my $self = shift;
my ($pfx, $io, $sub) = @{$self}{qw( pfx io sb )};
$self->{closed} and croak "Cannot print to closed filehandle";
my $fsep = defined $, ? $, : "";
my $rsep = defined $\ ? $\ : "";
my $line = $self->{line} . (join $fsep => @_) . $rsep;
my @line = split m/\n/, $line, -1;
$self->{line} = pop @line;
print { $io } map { _Filter_ (1, $pfx, $sub, $_) } @line;
} # PRINT
sub PRINTF {
my $self = shift;
my ($pfx, $io, $sub) = @{$self}{qw( pfx io sb )};
# Do not delegate this to PRINT, so we can prevent sprintf side effects
$self->{closed} and croak "Cannot print to closed filehandle";
my $fmt = shift;
$self->PRINT (sprintf $fmt, @_);
} # PRINTF
sub TELL {
my $self = shift;
$self->{closed} and croak "Cannot tell from a closed filehandle";
tell $self->{io};
} # TELL
sub EOF {
my $self = shift;
$self->{closed};
} # EOF
sub CLOSE {
my $self = shift;
my ($pfx, $io, $sub, $line) = @{$self}{qw( pfx io sb line )};
defined $line && $line ne "" and
print { $io } _Filter_ (0, $pfx, $sub, $line);
$self->{closed} or close $io;
$self->{line} = "";
$self->{closed} = 1;
} # CLOSE
sub UNTIE {
my $self = shift;
$self->{closed} or $self->CLOSE;
$self;
} # UNTIE
sub DESTROY {
my $self = shift;
$self->{closed} or $self->CLOSE;
%$self = ();
undef $self;
} # DESTROY
### ###########################################################################
sub _outputOnly {
my $name = shift;
sub { croak "No support for $name method: File is output only" };
} # _outputOnly
*read = _outputOnly ("read");
*READ = _outputOnly ("READ");
*readline = _outputOnly ("readline");
*READLINE = _outputOnly ("READLINE");
( run in 2.736 seconds using v1.01-cache-2.11-cpan-71847e10f99 )