in reply to Problems with Filehandles and TeeOutput

Looking at the source, the inputs to openTee must be a glob (ref(\$file) eq 'GLOB'), a string expression starting with ">" or ">>", or a file name (opened for append).

Based on some quick testing (without the module), all of these should work

local *LOG; open(LOG, '>>test.out'); openTee(*STDOUT, *STDOUT, *LOG); my $fh = IO::File->new(">>test.out"); openTee(*STDOUT, *STDOUT, *$fh); open(my $fh, '>>', 'test.out'); openTee(*STDOUT, *STDOUT, *$fh); openTee(*STDOUT, *STDOUT, '>>test.out'); openTee(*STDOUT, *STDOUT, 'test.out');

By the way, why do you want to use IO::File instead of open anyway?

Replies are listed 'Best First'.
Re^2: Problems with Filehandles and TeeOutput
by hkpatv (Initiate) on Aug 26, 2008 at 05:24 UTC
    OK, here is the results of my testing:
    #Works local *LOG; open(LOG, '>>test.out'); openTee(*STDOUT, *STDOUT, *LOG); #Does not work my $fh = IO::File->new(">>test.out"); openTee(*STDOUT, *STDOUT, *$fh); #Does not work open(my $fh, '>>', 'test.out'); openTee(*STDOUT, *STDOUT, *$fh); #Does not work open(my $fh, '>>', 'test.out'); openTee(*STDOUT, *STDOUT, *$fh); #Works openTee(*STDOUT, *STDOUT, '>>test.out'); #Works openTee(*STDOUT, *STDOUT, 'test.out');
    Note the resason I am using IO::File is because actually I want to use IO::File->new_tmpfile, but as that doesn't work I am trying IO::File->new to make testing easier. Note the only reason I was trying to get new_tmpfile working was cause I couldn't get it into a string using scalar I/O
    open($fh, "+<", \$string);
      Sorry, but the module you are using wasn't written to work on lexical handles, introduced over 8 years ago with 5.6.

      Update: IO::Tee appears to work with lexical file handles as well.

        Thanks, IO::Tee gets me a little bit closer
        #!/usr/bin/perl -w use strict; use warnings; use IO::Tee; use IO::File; my $stdout; open(my $fh, "+<", \$stdout); my $tee = new IO::Tee(\*STDOUT, $fh); print $tee `echo Test`; print $stdout;
        However I am actually trying to capture STDERR, so this code isn't that useful to me. I have tried IO::CaptureOutput but I can't get that working. Note apologies, as I know that this (capturing STDERR to local variable as well as directing to file) has been covered many times before perlmonks and elsewhere, but I haven't come across a definitive solution - I was hoping that TeeOutput would be the answer, I guess not.
      I couldn't help but notice that you used
      #Does not work open(my $fh, '>>', 'test.out'); openTee(*STDOUT, *STDOUT, *$fh);
      instead of
      #Should be working open(my $fh, '>>', 'test.out'); openTee(*STDOUT, *STDOUT, $fh); #asterisks ONLY before STDOUT, NOT $fh
      would you mind testing once more?
      []s, HTH, Massa (κς,πμ,πλ)

        That was intentional. It definitely won't work without the asterisk because the module expects a glob, not a reference to one.

        >perl -le"open(my $fh,'>','foo'); print( (ref(\$fh) eq 'GLOB') ?1:0)" 0

        That needs to be 1 or that module will stringify the handle.

        Tested, still not working.
        #!/usr/bin/perl -w use Local::TeeOutput; use strict; #No, still not working... open(my $fh, '>>', 'test2.out'); openTee(*STDOUT, *STDOUT, $fh); print "XX\n"; close($fh);
        Note it creates a file called GLOB(0x239bcc) which contains the correct data. Note I have been further reading simlar threads on perlmonks and elsewhere for what I am actually trying to do (write STDERR to file and save as variable). The solutions I have found are very complicated and work only on Unix (mine needs to be windows and unix compatible). Coming to the conclusion that the solution, if it exists will be take considerable effort which is likely not worthwile. I was hoping TeeOutput would be a quick solution, but it looks like it won't be suitable.