如何使用Perl打印到变量?
我一直在研究一个程序,以高度冗长的方式记录其迭代进度......
print $loghandle $some_message;
但是,我还想有选择地将一些消息打印到不同的文件中。当然,我可以将代码撒上......
print $loghandle $some_message
print $otherloghandle $some_message
或者将整个业务重写为一个功能。等等。
当我打开$ loghandle时,我想做的就是做一些魔术,这样当我print
时,我实际上只是对一个变量进行sprintf
ish操作(称之为$current_iteration
),这样当我到达决策点时,我可以做这样的事情......
print $real_log_file $current_iteration;
print $other_real_log_file $current_iteration if($condition);
我很确定我在某个地方见过这样的东西,但我不知道它在哪里或在哪里看。
编辑:File :: Tee在某种程度上在* nix上解决了这个问题,但我在Windows上运行。
答案 0 :(得分:19)
您可以通过open
将标量变量视为文件句柄:
open my $fh, '>', \$variable or die "Can't open variable: $!";
print $fh "Treat this filehandle like any other\n";
您甚至可以将stdout或stderr映射到标量:
close STDOUT;
open STDOUT, '>', \$variable or die "Can't open STDOUT: $!";
如果您要分割输出或设置配置文件以便在日志记录中执行“有趣”操作,那么最好使用其他人建议的Log4Perl。
答案 1 :(得分:5)
你的意思是IO::Scalar吗?允许您使用文件句柄语义写入变量。
答案 2 :(得分:4)
如果要进行选择性日志记录,您可以控制记录哪些消息以及记录哪些消息,请使用Log::Log4perl。这将为你节省大量时间,而不是弄乱tie
和其他黑魔法。
答案 3 :(得分:2)
您可以使用File::Tee将文件句柄拆分为多个输出流。
use File::Tee;
open my $fh, '>', 'logfile.txt' or die $!;
tee( $fh, '>', 'otherlogfile.txt' ) if $condition;
print $fh $current_iteration; # will also go to otherlogfile.txt
# if $condition was true
答案 4 :(得分:2)
Perlfaq5建议Tie::FileHandle::Multiplex打印到多个文件。
源代码非常简单,使用每个句柄过滤器很容易修改。
答案 5 :(得分:1)
听起来像是tie
你的文件句柄。
my $x;
# printing to $fh will update the variable $x
# when you close $fh, it will print $x to a filehandle depending
# on code in the function Print_to_variable::CLOSE
tie $fh, "Print_to_variable", \$x, $output_fh1, $output_fh2;
print $fh "stuff";
print $fh "more stuff";
close $fh;
sub Print_to_variable::TIEHANDLE {
my ($class, $ref, $fh1, $fh2) = @_;
my $self = {};
$self->{ref} = $ref;
$self->{output_fh1} = $fh1;
$self->{output_fh2} = $fh2;
bless $self, "Print_to_variable";
$self;
}
sub Print_to_variable::PRINT {
my ($self,@list);
${$self->{ref}} .= join "", @list;
}
sub Print_to_variable::CLOSE {
my $self = shift;
my $text = ${$self->{ref}};
if ( &myCondition1($text) ) { # ... how you decide where to print
print {$self->{output_fh1}} $text;
} else {
print {$self->{output_fh1}} $text;
}
}
答案 6 :(得分:1)
这是一个巨大的 hack,我认为mobrule的解决方案或(特别是)Sinan的Log4Perl解决方案是我有时间的方式。
但是,这就是我正在使用的,作为完成的事情:
sub print_to_var($$) {
my($rx_var, $scalar) = @_;
$$rx_var .= $scalar;
}
print_to_var \$logvar, $message;
#...later on...
print $somefile $logvar;
编辑:
由于这是社区维基,所以Perl别名函数的参数是没有价值的。这意味着你可以写下这个:
sub print_to_var($$) {
$_[0] .= $_[1];
}
然后说:
my $foo = "OH HAI. ";
print_to_var $foo, "I ARE HELO KITTIE.";
say $foo; # OH HAI. I ARE HELO KITTIE.
虽然print_to_var
打字的次数比.
多得多,但这并不是特别严重的黑客攻击。
这是HELO KITTIE:
helo kittie http://blogs.philadelphiaweekly.com/style/files/2008/11/hello-kitty-color.gif