从其他类方法重定向打印流

时间:2017-09-19 10:50:51

标签: perl oop logging

说我有一个Parent和Child类。 我只能修改Child类。

父类中有一些print

package Parent;

use strict;
use warnings;

sub new
{
    my $class = shift;
    my $self = {};
    bless $self, $class;
    return $self;
}

sub sayHello{
    my $self = shift;
    print "Hello world\n";
}

sub sayBye{
    my $self = shift;
    print "Bye world\n";
}

1;

在我的Child类中,我有一种方法可以将内容打印到日志文件中。

package Child;

use strict;
use warnings;

use parent 'Parent';

sub new
{
    my $class = shift;
    my $self = $class->SUPER::new();
    return $self;
}

sub talk{
    my $self = shift;
    $self->sayHello;
    $self->sayBye;
}

sub talkToLog{
    my $self = shift;

    my $logName = 'file.log';

    $self->log($logName, $self->sayHello); # Here's my best (not working) try
    $self->log($logName, $self->sayBye);
}

sub log{
    my $self = shift;
    my $filename = shift;
    my $string = shift;
    open(my $fh, ">>", $filename) || die "Couldn't open file $filename: $!";
    print $fh $string;
    close $fh;
    return;
}

1;

问题:是否有某种方式可以捕获"来自Child类的那些打印流,并使用log方法记录该内容?

以下是我尝试使用的pl文件。

#!/usr/bin/perl

use strict;
use warnings;

use Child;
my $child = Child->new;

$child->talk;
$child->talkToLog;

它在控制台中打印:

Hello world
Bye world
Hello world
Bye world

2 个答案:

答案 0 :(得分:2)

你需要这样的东西:

sub talkToLog{
    my $self = shift;

    my $logName = 'file.log';
    my $output = '';

    open TOOUTPUT, '>', \$output or die "Can't open TOOUTPUT: $!";
    select TOOUTPUT;

    $self->sayHello;
    $self->log($logName, $output);

    $output = '';
    $self->sayBye;
    $self->log($logName, $output);

    select STDOUT;
}

答案 1 :(得分:1)

为了记录,基于ilux答案,我修改了Child类,添加了两个新方法来使代码更清晰:buffer_startbuffer_get_clean

它们类似于PHP的ob_startob_get_clean方法,但您只需将buffer属性添加到类($self->{buffer})。

package Child;

use strict;
use warnings;

use parent 'Parent';

sub new
{
    my $class = shift;
    my $self = $class->SUPER::new();
    $self->{buffer} = '';    # <---- Note this
    return $self;
}

sub talk{
    my $self = shift;
    $self->sayHello;
    $self->sayBye;
}

sub talkToLog{
    my $self = shift;

    my $logName = 'file.log';

    # Cleaner way:

    $self->buffer_start;
    $self->sayHello;
    $self->log($logName, $self->buffer_get_clean);

    $self->buffer_start;
    $self->sayBye;
    $self->log($logName, $self->buffer_get_clean);
}

sub buffer_start{
    my $self = shift;
    open my $fh, '>>', \$self->{buffer};
    select $fh;
}

sub buffer_get_clean{
    my $self = shift;
    select STDOUT;
    my $buffer = $self->{buffer};
    $self->{buffer} = '';
    return $buffer;
}

sub log{
    my $self = shift;
    my $filename = shift;
    my $string = shift;
    open(my $fh, ">>", $filename) || die "Couldn't open file $filename: $!";
    print $fh $string;
    close $fh;
    return;
}

1;

希望这有帮助!