On Wed, 13 Dec 2006 13:51:22 -0800, Dean Arnold <[EMAIL PROTECTED]>
wrote:

> H.Merijn Brand wrote:
> > On Wed, 13 Dec 2006 11:31:00 -0800, Dean Arnold <[EMAIL PROTECTED]>
> > wrote:
> >>
> >> Has there been any thought to extending the target for
> >> trace() beyond simple filenames ? I'm looking for a means
> >> to supply either a coderef, or maybe an object implementing
> >> a simple print/write interface. My need is to be able to direct
> >> the traces to a centrally managed logging facility, and be able
> >> to turn them off/on as needed, e.g:
> > 
> > Instead of a coderef, I would suggest accepting file handles.
> > 
> > As the simple
> > 
> >     open my $handle, ">", \$scalar;
> > 
> > is a way to get your trace in a string if that would work, passing that
> > string to a sub would solve your case too. I've just done something similar
> > in a module that ties filehandles to functions, so if trace () were to 
> > accept
> > file handles in all allowed formats (also IO::Handle), that would be generic
> > enough to cover all needs.
> 
> To clarify, I presume you mean trace() is modified to support (possibly tied)
> filehandles in addition to simple filenames ? And then the app can supply
> a tied filehandle ?

More. As for most code speaks more than words, here's from the docs of my
module, which is very young and not ready for release yet:

pod:

 use PROCURA::OutputFilter;

 my $bucket = "";
 tie *STDOUT, "PROCURA::OutputFilter";
 tie *HANDLE, "PROCURA::OutputFilter", 4;
 tie *HANDLE, "PROCURA::OutputFilter", 4,  *STDOUT;
 tie *STDOUT, "PROCURA::OutputFilter", 4, \$bucket;
 tie *OUTPUT, "PROCURA::OutputFilter", 4,  *STDOUT, sub { "$_[0]" };

code:

sub TIEHANDLE
{
    my ($class, $lm, $io, $ref, $fno) = @_;

    $lm  //= 4;
    $io  //= *STDOUT;
    $ref //= sub { shift };

    ref $lm || $lm !~ m/^\d+$/  and
        croak "OutputFilter tie's 1st arg must be numeric";
    ref $ref eq "CODE"          or
        croak "OutputFilter tie's 3rd arg must be CODE-ref";

    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 {
        $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]);

A similar approach can be taken to interpret the second arg to trace ()

1. A plain scalar       Current behaviour       , "filename"
2. An IO::Handle Glob   IO::Handle object       , IO::Handle->new ()
3. A ref to scalar      PerlIO::Scalar IO       , \$buffer
4. A real IO glob       *STDOUT and such        , *STDOUT

Anything I missed?

-- 
H.Merijn Brand         Amsterdam Perl Mongers (http://amsterdam.pm.org/)
using & porting perl 5.6.2, 5.8.x, 5.9.x   on HP-UX 10.20, 11.00, 11.11,
& 11.23, SuSE 10.0 & 10.1, AIX 4.3 & 5.2, and Cygwin. http://qa.perl.org
http://mirrors.develooper.com/hpux/            http://www.test-smoke.org
                        http://www.goldmark.org/jeff/stupid-disclaimers/

Reply via email to