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.