Use UTF-8 in Log::StdLog?

J

jerry

I've been using Log::StdLog for logging, but find that when I tell it
to log a utf-8 string containing non-ASCII characters, I get the ol'
warning:

Wide character in print at....

Now, when writing to a file, the fix for this is

binmode (FILE, ":utf8") ;

But is there a way to fix Log::StdLog without going in and hacking the
source code?

Log::StdLog is initialized like this:

use Log::StdLog { level => 'all', file => "PerlRun.log"} ;

and then when you want to log a message, you do

print {*STDLOG} info => "This is a message.\n" ;

So, I probably need to do something like

binmode (STDLOG, ":utf8") ;

but I can't get any such syntax to work. I've looked at the
Log::StdLog source code but it's way over my head. I don't understand
what the asterisk does prefixing STDLOG. I thought that perl did not
have an asterisk dereferencing operator.

Thanks,

Jerry Krinock
 
A

anno4000

I've been using Log::StdLog for logging, but find that when I tell it
to log a utf-8 string containing non-ASCII characters, I get the ol'
warning:

Wide character in print at....

Now, when writing to a file, the fix for this is

binmode (FILE, ":utf8") ;

But is there a way to fix Log::StdLog without going in and hacking the
source code?

Log::StdLog is initialized like this:

use Log::StdLog { level => 'all', file => "PerlRun.log"} ;

and then when you want to log a message, you do

print {*STDLOG} info => "This is a message.\n" ;

So, I probably need to do something like

binmode (STDLOG, ":utf8") ;

try

binmode \ *STDLOG, ':utf8';
but I can't get any such syntax to work. I've looked at the
Log::StdLog source code but it's way over my head. I don't understand
what the asterisk does prefixing STDLOG. I thought that perl did not
have an asterisk dereferencing operator.

It doesn't. The asterisk refers to the typeglob associated with a
package variable. See "typeglob" in perldata.

Anno
 
M

Mumia W.

I've been using Log::StdLog for logging, but find that when I tell it
to log a utf-8 string containing non-ASCII characters, I get the ol'
warning:

Wide character in print at....

Now, when writing to a file, the fix for this is

binmode (FILE, ":utf8") ;

But is there a way to fix Log::StdLog without going in and hacking the
source code?

Log::StdLog is initialized like this:

use Log::StdLog { level => 'all', file => "PerlRun.log"} ;

and then when you want to log a message, you do

print {*STDLOG} info => "This is a message.\n" ;

So, I probably need to do something like

binmode (STDLOG, ":utf8") ;

but I can't get any such syntax to work. I've looked at the
Log::StdLog source code but it's way over my head. I don't understand
what the asterisk does prefixing STDLOG. I thought that perl did not
have an asterisk dereferencing operator.

Thanks,

Jerry Krinock

Perl does not have an asterisk dereferencing operator, and the symbol
isn't needed here (but doesn't hurt).

You can solve the problem three ways: (1) Reach deep into the internals
of the tied object and set binmode on the handle :-( . (2) Create your
own file handle to receive logging information and specify the "handle"
option when you "use Log::StdLog". (3) Shove an extra BINMODE method
into the author's Log::StdLog package :-( :-(

Here is code to demonstrate the various methods:
(1)
use strict;
use warnings;
use Log::StdLog { level => 'warn', file => 'here.log' };

print {*STDLOG} warn => 'First logging line';
binmode((tied *STDLOG)->{handle}, 'utf8');

print {*STDLOG} warn => "Hey, this (\x{263a}) is here.";

(2)
use strict;
use warnings;

my $logfh;
BEGIN {
open ($logfh, '>:utf8', 'here2.log') or die("Stopped: $!");
}
use Log::StdLog { level => 'warn', handle => $logfh };

print {*STDLOG} "The smiley <\x{263a}> is here.";

close $logfh;
(3)
use strict;
use warnings;

use Log::StdLog { level => 'warn', file => 'here.log' };

print {*STDLOG} warn => 'initializer';
binmode(STDLOG, 'utf8');
print {*STDLOG} warn => "The smiley <\x{263a}> is here.";
print STDLOG warn => 'More logging...';
print $Log::StdLog::VERSION, "\n";

sub Log::StdLog::BINMODE {
my ($self, $mode) = @_;
binmode($self->{handle}, $mode);
$self;
}

Note that, for (1) and (3) to work, some data must have already been
written to the file. You might make a feature request of the author for
binmode() support.
 
J

Jerry Krinock

Ah, perldata! Well, search engines don't work very well when you're
looking for "*". But you folks are great; thank you very much.
Thanks especially to Mumia for the shortcut to the code. Of course, I
used your non-hacky solution (2).

you might make a feature request of the author for binmode() support.

I just did that. CPAN ticket 28232.

Thanks again,

Jerry
 
J

Jerry Krinock

Just one little correction in case someone else tries this, in Mumia's
code (2) the mode needs to be '>>:utf8' to append, instead of
'>:utf8'.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top