在 $fh 上调用 'print' 时有没有办法得到通知?

Is there a way to be notified when 'print' is called on $fh?

当我这样做时:

print $fh 'text';

我需要一些 &sub 才能被调用。

有办法吗?

您可以 tie a filehandle 并自定义 print 对该文件句柄或对该文件句柄的任何其他操作的行为。

sub PrintNotifier::TIEHANDLE {
    my ($pkg, $orignalHandle) = @_;
    bless { glob => $orignalHandle }, $pkg;
}
sub PrintNotifier::PRINT {
    my ($self,@msg) = @_;
    ... do whatever you want with @msg here ...
    return print {$self->{glob}} @msg;
}
sub PrintNotifier::CLOSE { return close $_[0]->{glob} }

open my $fh, '>', 'some-file';
tie *$fh, 'PrintNotifier', $fh;
print $fh "something";           # calls  PrintNotifier::PRINT

你可以 tie 手柄,正如暴民建议的那样。或者,如果你可以更改代码并且你的 Perl 足够新,你可以替换

print $fh 'text';

$fh->print('text');

您可能会考虑更简洁的语法;那么你可以子classIO::File:

package MyFH {
    use parent qw/ IO::File /;
    use mro; # Get next::method

    sub print {
        my ($self, @args) = @_;

        warn 'Printing ', @args;
        $self->next::method(@args);
    }
}

my $fh = MyFH->new();
$fh->open('file', '>') or die $!;

然而,这并没有抓住老式

print $fh 'text';

风格。

根据您的喜好,您可能会发现新样式更简洁,因为如果您的文件句柄是表达式,它允许

$obj->method()->print('text');

而不是

print {$obj->method()} 'text';

它对 Perl 5.14 及更高版本透明地工作,并且可以通过添加

使其适用于回到(至少)5.8 的旧 Perl
use IO::Handle;

到要在其中使用它的文件的顶部(为了安全起见)。

In 未记录在 perl but has usefull usage

如果你想在你的 class 中处理你的对象上的 print,你可以 tie 到它本身:

tie *$self, $self;
print $self 'text';
$self->print( 'text' );