Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which Perl built-ins cannot be overridden in CORE::GLOBAL?

Tags:

perl

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 or grep) can't be overridden.

What is the full list?

like image 335
Greg Bacon Avatar asked Sep 09 '10 17:09

Greg Bacon


3 Answers

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

like image 142
John Feminella Avatar answered Nov 23 '22 14:11

John Feminella


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";
}
like image 31
Chas. Owens Avatar answered Nov 23 '22 13:11

Chas. Owens


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.

like image 32
mob Avatar answered Nov 23 '22 15:11

mob