我已经定义了一堆功能,这些功能做了很多工作并且有一堆打印语句。可以这样调用它们来构建一个html页面。
print_A()
print_B()
print_C()
现在,我想调用这些函数并将这些print语句的内容存储到一个主变量中。一种方法是重写这些函数,使它们返回一个包含其内容的字符串(而不是打印)
my $var = "";
$var = $var . store_A();
$var = $var . store_B();
$var = $var . store_C();
但我想在不修改或重写功能的情况下这样做。我不想通过这么小的改变来重新定义这些功能(程序中有数百个这样的功能)。
在perl中有更短更快的方法吗?
答案 0 :(得分:11)
一种方法是使用select将STDOUT重定向到标量变量:
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"}
打印出来:
start
s1
s2
end
答案 1 :(得分:1)
根据这些函数的功能,您可以在子进程中运行它们并捕获它们的输出:
my $pid = open(PIPE, "-|");
if (0 == $pid) {
# Child
print_A();
print_B();
print_C();
exit(0);
}
else {
my $var = "";
while(<PIPE>) {
$var .= $_;
}
close(PIPE);
}
您必须评估将这些函数调用移动到子进程是否安全。如果其中一个函数更改了进程的全局状态 - 例如,如果它修改了一个全局变量 - 那么该更改将仅限于子进程,并且不会在原始脚本进程中发生。
答案 2 :(得分:0)
您还可以使用IO :: Scalar将变量绑定到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!
与@ toolic的答案没有实际区别。