The Overriding Built-in Functions section of the perlsub documentation provides
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::
.
and then gives a few examples. At the end, however, is
Finally, some built-ins (e.g.
exists
orgrep
) can't be overridden.
What is the full list?
Any value that is negative in toke.c
can be overridden; all others may not. You can look at the source code here.
For example, let's look at waitpid
on line 10,396:
case 'w':
if (name[1] == 'a' &&
name[2] == 'i' &&
name[3] == 't' &&
name[4] == 'p' &&
name[5] == 'i' &&
name[6] == 'd')
{ /* waitpid */
return -KEY_waitpid;
}
Since waitpid
is negative, it may be overridden. How about grep
?
case 'r':
if (name[2] == 'e' &&
name[3] == 'p')
{ /* grep */
return KEY_grep;
}
It's positive, so it cannot be overridden. That means that the following keywords cannot be overridden:
chop, defined, delete, do, dump, each, else, elsif, eval, exists, for, foreach, format, glob, goto, grep, if, keys, last, local, m, map, my, next, no, package, pop, pos, print, printf, prototype, push, q, qq, qw, qx, redo, return, s, scalar, shift, sort, splice, split, study, sub, tie, tied, tr, undef, unless, unshift, untie, until, use, while, y
The prototype
function will tell you if you can override a CORE::
function.
Here is a hacked together attempt to get all the functions without having to type them:
#!/usr/bin/perl
use strict;
use warnings;
open my $fh, "-|", "perldoc", "-u", "perlfunc" or die $!;
my %seen;
while (<$fh>) {
next unless my ($func) = /=item ([a-z]\w+)/;
next if $seen{$func}++;
my $prototype = prototype "CORE::$func";
print "$func is ", defined $prototype ? "overiddable with $prototype " :
"not overiddable", "\n";
}
The readline(HANDLE)
function (and the equivalent <HANDLE>
I/O operator) can be mocked, but its behavior of auto-assigning to $_
when used like
while (<HANDLE>) { ... # equivalent to while (defined($_=readline(HANDLE)))
cannot be. See hobbs comment at How can I still get automatic assignment to '$_' with a mocked 'readline' function?. This means code like
while (<>) { # implicitly sets $_
do_something_with($_);
}
will probably break if you redefine readline
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With