4

When I do:

print $fh 'text';

I need a some &sub to be called.

It there a way to do that?

TLP
  • 66,756
  • 10
  • 92
  • 149
Eugen Konkov
  • 22,193
  • 17
  • 108
  • 158

3 Answers3

4

You can tie a filehandle and customize the behavior for printing to that filehandle or for any other operation on that filehandle.

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
mob
  • 117,087
  • 18
  • 149
  • 283
2

You can tie the handle, as mob suggested. Or, if you can change the code and your Perl is new enough, you can replace

print $fh 'text';

with

$fh->print('text');

which you might consider cleaner syntax; then you can sub-class IO::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 $!;

However, this doesn't capture the old-fashioned

print $fh 'text';

style.

Depending on your preference, you might find the new style cleaner anyway, since if your file handle is an expression it allows

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

instead of

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

It works transparently for Perl 5.14 and up, and can be made to work for older Perls back to (at least) 5.8 by adding

use IO::Handle;

to the top of the files you want to use it in (just to be on the safe side).

Jonathan Cast
  • 4,569
  • 19
  • 34
0

In is not documented in perl but has usefull usage

If you want to process print'ing on your object in your class you can tie into itself:

tie *$self, $self;
print $self 'text';
$self->print( 'text' );
Eugen Konkov
  • 22,193
  • 17
  • 108
  • 158