princepawn has asked for the wisdom of the Perl Monks concerning the following question:

I want to print something to a file and to STDOUT. I am doing it in this repetitive way now and wanted to use a map or for statement to do it:
open R, ">register.log" or die "can't open register:!"; my $log = "[$label] inserted as\n[$sql]\n"; print R $log; print $log;

Replies are listed 'Best First'.
Re: mapping through filehandles
by larsen (Parson) on Oct 28, 2001 at 19:37 UTC
    See perlman:perldata. Here an example:
    my $log = "Hello World!"; my $stdout_handler = \*STDOUT; my $r_handler = \*R; # R has been open()-ed as usual map { print $_ $log } ($stdout_handler, $r_handler);
      No need for map in void context:
      print $_ $log for \*STDOUT, \*R;
      P.S. I think I saw this from tye in the CB awhile back :-)
      That can be simplified to
      map { print $_ $log } (STDOUT, R);
      without the need for the $stdout_handler or $r_handler.
        Yes, as Anonymous Monk said, one could be lazy, without using any reference to file handles, but this practice has the backlash that is does not work using strict. A solution (but I personally don't like it) is to use a throw-away block in order to conjuring with barewords without strict:
        { no strict; map { print $_ $log } (STDOUT, R); } $foo = "bar"; # Error! here we're re-using string

        Update: runrig's one is the best way to be lazy :)

Re: mapping through filehandles
by Fletch (Bishop) on Oct 28, 2001 at 23:49 UTC

    There's this, or the more fully featured IO::Tee module on CPAN.

    package TeeHandle; use Carp; use Symbol (); sub TIEHANDLE { my( $class, $file, $dst_handle ) = @_; my $handle = Symbol::gensym; # Make a filehandle name my $true_handle = Symbol::gensym; open( $true_handle, ">&$dst_handle" ) or croak "Can't dup handle '$dst_handle': $!"; open( $handle, ">$file" ) or croak "Can't create '$file': $!"; return bless { handle => $handle, true => $true_handle }, $class; } sub PRINT { my $self = shift; for (@_) { print {$self->{handle}} "$_"; print {$self->{true}} "$_"; } } 1; __END__ package main; use Carp; use Symbol (); tie *STDOUT => 'TeeHandle', "out", 'STDOUT'; tie *STDERR => 'TeeHandle', "err", 'STDERR'; print "Testing . . .\n"; print STDERR "This goes to STDERR\n"; CORE::warn "Where do I go?\n"; ## This doesn't work. system '/bin/sh', '-c', 'echo "Testing if it\'s propigated" 1>&2'; exit 0;