On Fri, Dec 15, 2006 at 01:01:31PM -0800, Dean Arnold wrote:
> OK, its working.
> 
> However, it appears tied filehandles have been either deprecated in
> favor of custom layers, or just don't work from XS yet.

Uh [groan], yes, tieing is implemented in the perl op code layer
(ie pp_print() in pp_hot.c) well 'above' PerlIO. So it has to be done
by layers to work with XS code.

> In any event,
> I switched to a custom layer test and things work OK.

Great.

> I still have to add the logic to PurePerl, and do some
> testing on non Win32 platforms, but hope to deliver the
> update by Monday. Do you want to review it all before
> I commit to svn ?

Go ahead and check it in!

> - Dean
> 
> =head2 Tracing to Layered Filehandles

Its worth saying up-front that a tied filehandle won't work, as that's
what most people would naturally try to use.

> One application of tracing to existing filehandles is the use of layered
> filehandles (using L<PerlIO::via> custom layering), thereby providing a
> mechanism to adapt DBI's tracing to an existing logging facility. E.g.,

I'd like to see a "most simple" example come first in the docs.
Perhaps something that just appends the trace messages into a scalar
variable. Would this work?:

    open( my $fh, "+<:scalar", \$scalar );
    $dbh->trace( 2, $fh );

>       package PerlIO::via::TraceDBI;

A reference in the docs to the PerlIO::via docs would be handy.

It's probably beter not to include DBI in the name of the package.
There's nothing DBI related here, it's 'just' a PerlIO layer interface to
some logging software and could be used on other filehandles.
So it could be called PerlIO::via::MyFancyLogLayer, for example.

>       my $logger;
>       sub logger { $logger = shift; }
>
>       sub PUSHED {
>           my ($class,$mode,$fh) = @_;
>           my $buf;
>           return bless \$buf,$class;
>       }

Rather than have a logger sub to inject the logger object into a
package global, I *think* you could do this:

        sub PUSHED {
            my ($class,$mode,$fh) = @_;
            my $logger; # set via OPEN
            return bless \$logger, $class;
        }
        sub OPEN {
            my ($obj,$path,$mode,$fh) = @_;
            $$obj = $path; # $path is logger object to use
            return 1; # ?
        }
        sub WRITE {
            my ($obj,$buf,$fh) = @_;
            $obj->log($buf);
            return length($buf);
        }

and then in your application:

        use PerlIO::via::MyFancyLogLayer;
  
        open my $fh, '>:via(MyFancyLogLayer)', MyFancyLogger->new();

        $dbh->trace('SQL', $fh);

Apart from being neater it would allow multiple filehandles to use
PerlIO::via::MyFancyLogger each with different logger objects.

I hope that, or something like it, will work.

Thanks again Dean. Great work.

Tim.

Reply via email to