=head1 NAME FileHandle::Sub - an output filehandle that sends each line of output to a user-specified CODE block =head1 SYNOPSIS use FileHandle::Sub; # grep my $fh = FileHandle::Sub::open { /token/ and print }; # prefix my $fh = FileHandle::Sub::open { s/^/scalar localtime/e; print }; =head1 DESCRIPTION Each line of output sent to this file handle will be passed to the CODE block supplied to C. =cut package FileHandle::Sub; { require 5.8.0; use strict; use warnings; sub open (&) { local *FH; tie *FH, __PACKAGE__, @_ or return; return *FH; } sub TIEHANDLE { my($class, $code) = @_; bless [$code, ""], $class; } sub _emit { my ($self, $txt) = @_; my ($code, $prev) = @$self; if ($txt =~ /\n$/) { local $_ = $prev . $txt; $code->($_); $prev = ""; } else { $prev .= $txt; } $self->[1] = $prev; } sub PRINT { my ($self, @txt) = @_; local $_; for my $txt (@txt) { _emit($self, $_) for $txt =~ /[^\n]*\n?/g; } } sub PRINTF { my ($self, $fmt, @args) = @_; PRINT $self, sprintf $fmt, @args; } sub CLOSE { my ($self) = @_; local $_ = $self->[1]; if (length) { $self->[0]->($_); } $self->[1] = ""; } sub DESTROY { &CLOSE } } 1;