简体   繁体   中英

How can I print to a variable in Perl?

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?

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM