Printing to multiple files ... without changing my code.

Joel Bernstein joel at
Fri Sep 15 17:23:27 BST 2006

On Fri, Sep 15, 2006 at 04:20:37PM +0100, McGlinchy, Alistair wrote:
> Joel Bernstein wrote:
> > I'd say the best way is to tie 
> > STDOUT, which I've just hacked up a demo of:
> I didn't know you tie a file handle. Very cool!  

Sure you can. Any scalar, array, hash or filehandle can be tied. Read
perldoc perltie and take a look at the modules Tie::Scalar, Tie::Array,
Tie::Hash and Tie::Handle for a starting point.

> There's a wee bit of a performance hit using this method but well worth
> the effort.

Well, yes. The version I gave you just concatenates a scalar and writes
out at END{} time. So it's not as slow as it would be if you flushed the
buffer every time you called print. But it's not as fast as just calling
print, which is a builtin written in highly-optimised C code.

> Benchmark: timing 10 iterations of normal, tied...
>     normal:  9 wallclock secs ( 7.55 usr +  0.20 sys =  7.75 CPU) @
> 1.29/s (n=10)
>       tied: 19 wallclock secs (17.41 usr +  0.16 sys = 17.56 CPU) @
> 0.57/s (n=10)
> ... Ooh and I can do this with any file handle. This opens up several
> possibilities. My log files will never know what's hit them. Buahahahar!

If you're using this for logging, there're other options available to
you. You could log to syslog and configure syslogd to write to multiple
files. You could use Log::Log4perl which supports multiple appenders.
I'm fairly sure Log::Dispatch can do that, too.

> Thanks for the great example.

I'd say you might find it more intuitive to tie a standard fh rather
than STDOUT, and then use the one-argument form of select() to redirect
STDOUT to that fh. But it's effectively the same thing.

Glad you like it. It feels a bit cracky, mind you, especially as you
could just run your script unchanged and pipe it into tee(1) which will
do the job fine outside of perl-land. Out of interest, why did you not
just do that?


More information about the mailing list