perlredefine

How do I redefine built-in Perl functions?


I want to do two things:

In production code, I want to redefine the open command to enable me to add automagic file logging. I work on data processing applications/flows and as part of that, it's important for the user to know exactly what files are being processed. If they are using an old version of a file, one way for them to find out is by reading through the list of files being processed.

I could just create a new sub that does this logging and returns a file pointer and use that in place of open in my code.

It would be really nice if I could just redefine open and have pre-existing code benefit from this behavior. Can I do this?

In debug code, I'd like to redefine the printf command to insert comments along with the written output indicating which code generated that line. Again, I have a sub that will optionally do this, but converting my existing code is tedious.


Solution

  • For open: This worked for me.

    use 5.010;
    use strict;
    use warnings;
    use subs 'open';
    use Symbol qw<geniosym>;
    
    sub open (*$;@) { 
        say "Opening $_[-1]";
        my ( $symb_arg ) = @_;
        my $symb;
        if ( defined $symb_arg ) { 
            no strict;
            my $caller = caller();
            $symb = \*{$symb_arg};
        }
        else { 
            $_[0] = geniosym;
        }
        given ( scalar @_ ) { 
            when ( 2 ) { return CORE::open( $symb // $_[0], $_[1] ); }
            when ( 3 ) { return CORE::open( $symb // $_[0], $_[1], $_[2] ); }
        }
        return $symb;
    }
    
    open PERL4_FH, '<', 'D:\temp\TMP24FB.sql';
    open my $lex_fh, '<', 'D:\temp\TMP24FB.sql';
    

    For Printf: Did you check out this question? -> How can I hook into Perl’s print?