- publishing free software manuals
Perl Language Reference Manual
by Larry Wall and others
Paperback (6"x9"), 724 pages
ISBN 9781906966027
RRP £29.95 ($39.95)

Sales of this book support The Perl Foundation! Get a printed copy>>>

8.10 Overriding Built-in Functions

Many built-in functions may be overridden, though this should be tried only occasionally and for good reason. Typically this might be done by a package attempting to emulate missing built-in functionality on a non-Unix system.

Overriding may be done only by importing the name from a module at compile time--ordinary predeclaration isn't good enough. However, the use subs pragma lets you, in effect, predeclare subs via the import syntax, and these names may then override built-in ones:

use subs 'chdir', 'chroot', 'chmod', 'chown';
chdir $somewhere;
sub chdir { ... }

To unambiguously refer to the built-in form, precede the built-in name with the special package qualifier CORE::. For example, saying CORE::open() always refers to the built-in open(), even if the current package has imported some other subroutine called &open() from elsewhere. Even though it looks like a regular function call, it isn't: you can't take a reference to it, such as the incorrect \&CORE::open might appear to produce.

Library modules should not in general export built-in names like open or chdir as part of their default @EXPORT list, because these may sneak into someone else's namespace and change the semantics unexpectedly. Instead, if the module adds that name to @EXPORT_OK, then it's possible for a user to import the name explicitly, but not implicitly. That is, they could say

use Module 'open';

and it would import the open override. But if they said

use Module;

they would get the default imports without overrides.

The foregoing mechanism for overriding built-in is restricted, quite deliberately, to the package that requests the import. There is a second method that is sometimes applicable when you wish to override a built-in everywhere, without regard to namespace boundaries. This is achieved by importing a sub into the special namespace CORE::GLOBAL::. Here is an example that quite brazenly replaces the glob operator with something that understands regular expressions.

package REGlob;
require Exporter;
@ISA = 'Exporter';
@EXPORT_OK = 'glob';
sub import {
    my $pkg = shift;
    return unless @_;
    my $sym = shift;
    my $where 
        = ($sym =~ s/^GLOBAL_// ? 'CORE::GLOBAL' : caller(0));
    $pkg->export($where, $sym, @_);
}
sub glob {
    my $pat = shift;
    my @got;
    if (opendir my $d, '.') { 
        @got = grep /$pat/, readdir $d; 
        closedir $d;   
    }
    return @got;
}
1;

And here's how it could be (ab)used:

#use REGlob 'GLOBAL_glob';      # override glob() in ALL namespaces
package Foo;
use REGlob 'glob';              # override glob() in Foo:: only
print for <^[a-z_]+\.pm\$>;     # show all pragmatic modules

The initial comment shows a contrived, even dangerous example. By overriding glob globally, you would be forcing the new (and subversive) behavior for the glob operator for every namespace, without the complete cognizance or cooperation of the modules that own those namespaces. Naturally, this should be done with extreme caution--if it must be done at all.

The REGlob example above does not implement all the support needed to cleanly override perl's glob operator. The built-in glob has different behaviors depending on whether it appears in a scalar or list context, but our REGlob doesn't. Indeed, many perl built-in have such context sensitive behaviors, and these must be adequately supported by a properly written override. For a fully functional example of overriding glob, study the implementation of File::DosGlob in the standard library.

When you override a built-in, your replacement should be consistent (if possible) with the built-in native syntax. You can achieve this by using a suitable prototype. To get the prototype of an overridable built-in, use the prototype function with an argument of "CORE::builtin_name" (see ).

Note however that some built-ins can't have their syntax expressed by a prototype (such as system or chomp). If you override them you won't be able to fully mimic their original syntax.

The built-ins do, require and glob can also be overridden, but due to special magic, their original syntax is preserved, and you don't have to define a prototype for their replacements. (You can't override the do BLOCK syntax, though).

require has special additional dark magic: if you invoke your require replacement as require Foo::Bar, it will actually receive the argument "Foo/Bar.pm" in @_. See .

And, as you'll have noticed from the previous example, if you override glob, the <*> glob operator is overridden as well.

In a similar fashion, overriding the readline function also overrides the equivalent I/O operator <FILEHANDLE>. Also, overriding readpipe also overrides the operators `` and qx//.

Finally, some built-ins (e.g. exists or grep) can't be overridden.

ISBN 9781906966027Perl Language Reference ManualSee the print edition