mnj200g has asked for the wisdom of the Perl Monks concerning the following question:
Hi.
I am a beginner and need some PERL help. I am testing a function that I cannot change. I need to capture the print statements from this funtion. For example, the following function:
sub_I_can't_change($$$)
{
code
code
print "line 1\n";
print "line 2\n";
return code;
}
How do I capture the outputs that it prints to the screen. I would prefer to capture the data into a variable if possible.
Thanks.
MNJ
Comment on Need Help: Capture Print Outputs from a Function
#! perl -sw
use strict;
sub immutable {
print "immutable received args: [ @_ ]\n";
print "Some more stuff\n";
}
## Save a copy of STDOUT
open SAVED, '>&=STDOUT';
close STDOUT;
## Open STDOUT to a variable (ramfile)(Requires 5.8.x)
open STDOUT, '>', \ my( $var ) or die $!;
## Call the sub
immutable( qw[ some args here ] );
## Close the ramfile
close STDOUT;
## Redirect STDOUT back to it's original place
open STDOUT, '>&=SAVED' or die $!;
## Discard the backup
close SAVED;
## Use the captured output
print "The variable \$var now contains:\n'$var'\n";
__END__
C:\test>junk2
The variable $var now contains:
'immutable received args: [ some args here ]
Some more stuff
'
since the former restores STDOUT even in the case of exceptions. The former, however, doesn't work if someone has previously called select. I guess the comprehensive solution would be:
{
my $old_select = select();
my $handle = on_release { select($old_select); };
open local *STDOUT, '>', \$buf;
select(STDOUT);
...
}
#!/usr/bin/perl
use strict;
use warnings;
my ($buf);
{
local *STDOUT;
open( STDOUT, '>', \$buf ) or die "Write to buffer failed\n";
mysub();
}
print "buffer: $buf\n";
sub mysub{
print "mysub output\n";
}
It does not seem to be working. I get the following message:
Use of uninitialized value in concatenation (.) or string at scop/x.pl line 126.
buffer:
Line 126 is where print "buffer: $buf\n"; is.
Also, what is the structure under my ($buf); in your code? Is that how PERL creates a macro or what C calls prototypes?
I've also tried the first method mentioned above and that also fail to initialize the variable $var. In that first function, what is the significant of "qw"?
Thanks.
I get the following message: Use of uninitialized value in concatenation (.)
You're using a version of Perl older than 5.8.0, when open(STDOUT, '>', \$buf) was introduced. Before 5.8, \$buf would be stringified to something like SCALAR(0x1ab2760). The output ends up in a file by that name instead of going to $buf, so $buf is still undefined when you go to inspect it.
Thank you again to everyone. It is working. I did ran into the problem mentioned by BrowserUK where another function using select(STDOUT) and then setting "$| = 1;" (no buffering). That gave me the problem of $buf coming back empty.
I fixed that by setting buffer on ($| = 0) just before the local "scope".