in reply to Re: using Exporter to overwrite a core function
in thread using Exporter to overwrite a core function

well, here's basically the idea:
Package Foo; use strict; use Exporter; use vars qw(@EXPORT_OK); @EXPORT_OK = (&sysread); sub sysread { print "this is not the real thing\n"; } Package Bar; use Foo qw(sysread); print "about to test sysread\n"; sysread;
Basically this generates *both* the "this is not the real thing" message from the imported sub as well as the "not enough arguments for sysread" error message from the core call.

What really dazzles me is not even the fact that it doesn't quite work the way I want it to, but that in fact both functions are being called on.

Replies are listed 'Best First'.
Re^3: using Exporter to overwrite a core function
by tlm (Prior) on Apr 09, 2005 at 23:03 UTC

    I know you requested no lectures, but the code you posted had some fundamental errors that make me wonder whether it is a good idea for you to be playing with fire. It's your business if you want to hang yourself, but I feel uneasy handing you the rope for it. I just had to get this off my chest. OK, end of sermonette.

    I found at least three major errors in your code (more if all the code was intended to reside in a single file). The first one is that it's package, all lower case. What you wrote is equivalent to Foo->Package (see perlobj) . Next, it is not enough to use Exporter; you need to make your class a subclass of it. Like this:

    package Foo; use Exporter; our @ISA = ( 'Exporter' );
    or (my preferred idiom):
    package Foo; use base 'Exporter';
    (There are more idioms for doing this; see perlobj). The third thing is that the entries in @EXPORT, @EXPORT_OK, etc. are supposed to be strings. Something like @EXPORT_OK = ( &frobozz ) will put the value returned by the frobozz subroutine (whatever that is) in @EXPORT_OK, which, unless frobozz is the rare function that narcissistically returns its own name, won't do you any good.

    OK, so here's what you do:

    # file Foo.pm package Foo; use strict; use warnings; use Exporter; our @ISA = ( 'Exporter' ); our @EXPORT_OK = ( 'sysread' ); sub sysread { warn "this is not the real thing\n"; } 1; __END__ # file test.pl use strict; use warnings; package Bar; use Foo 'sysread'; warn "about to test sysread\n"; sysread; __END__ % perl test.pl about to test sysread this is not the real thing
    Note that the code in the example above is split over two files; it won't work as written if you put it all in one file.

    Definitely give a very good read or two to the relevant section of perlsub that I cited before.

    the lowliest monk

      indeed, a couple of nasty errors in there. Basically what I did was (rather too) quickly type in that part which was relevant, making some mistakes in the process. Typing Package instead of package is a habit I somehow managed to pick up and which, fortunately, my editor warns me about each time I make it. As for using strings, I didn't see anything about this in the documentation for Exporter, is this really a necessity?

      Long story short, adding the @ISA=('Exporter'); line did in fact resolve the problem, many thanks :-)