Reputation: 77
I have already defined a bunch of functions which do a lot of work and have a bunch of print statements. They can be called like so to build an html page.
print_A()
print_B()
print_C()
Now, I want to call these functions and store the contents of these print statements into one main variable. One way is to rewrite these functions so they return a string with their contents (instead of printing)
my $var = "";
$var = $var . store_A();
$var = $var . store_B();
$var = $var . store_C();
But I want to do this without modifying or rewriting the functions. I don't want to redefine these functions with such a minor change (there are hundreds of these functions in the program).
Is there a shorter and faster way to do this in perl?
Upvotes: 3
Views: 3750
Reputation: 1453
You can also use IO::Scalar to tie a variable to STDOUT.
use IO::Scalar;
my $output_str;
tie *STDOUT, 'IO::Scalar', \$output_str;
print "Hel", "lo, ";
print "world!\n";
untie *STDOUT;
print "output_str is $output_str\n";
# prints
# output_str is Hello, world!
Not effectively different from @toolic's answer though.
Upvotes: 0
Reputation: 25380
Depending on just what these functions do, you may be able to run them in a subprocess and capture their output:
my $pid = open(PIPE, "-|");
if (0 == $pid) {
# Child
print_A();
print_B();
print_C();
exit(0);
}
else {
my $var = "";
while(<PIPE>) {
$var .= $_;
}
close(PIPE);
}
You'll have to evaluate whether it's safe to move these function calls into a subprocess. If one of these functions changes the process's global state--for example, if it modifies a global variable--then that change will be confined to the child process, and won't happen in the original script process.
Upvotes: 1
Reputation: 62019
One way is to use select to redirect STDOUT to a scalar variable:
use warnings;
use strict;
my $out;
open my $fh, '>', \$out;
my $old_stdout = select $fh;
s1();
s2();
select $old_stdout;
close $fh;
print "start\n";
print $out;
print "end\n";
sub s1 {print "s1\n"}
sub s2 {print "s2\n"}
Prints out:
start
s1
s2
end
Upvotes: 12