Какие встроенные модули Perl нельзя переопределить в CORE:: GLOBAL?

Переопределение встроенных функций в документации perlsub обеспечивает

Существует второй метод, который иногда применим, когда вы хотите переопределить встроенную систему везде, независимо от границ пространства имен. Это достигается путем импорта sub в специальное пространство имен CORE::GLOBAL::.

а затем дает несколько примеров. В конце, однако,

Наконец, некоторые встроенные модули (например, exists или grep) не могут быть переопределены.

Каков полный список?

Ответы

Ответ 1

Любое отрицательное значение в toke.c может быть переопределено; все остальные не могут. Вы можете посмотреть исходный код здесь.

Например, рассмотрим waitpid в строке 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;
      }

Так как waitpid отрицательный, он может быть переопределен. Как насчет grep?

        case 'r':
          if (name[2] == 'e' &&
              name[3] == 'p')
          {                                   /* grep       */
            return KEY_grep;
          }

Это положительно, поэтому его нельзя переопределить. Это означает, что следующие ключевые слова нельзя переопределить:

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

Ответ 2

Функция prototype сообщит вам, можете ли вы переопределить функцию CORE::.

Вот взломанная попытка собрать все функции, не набирая их:

#!/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";
}

Ответ 4

Функция readline(HANDLE) (и эквивалентный оператор ввода/вывода <HANDLE>) может быть издеваема, но ее поведение авто- присваивая $_ при использовании как

while (<HANDLE>) { ...    # equivalent to   while (defined($_=readline(HANDLE)))

быть не может. См. Комментарий к hobbs в Как я могу получить автоматическое присвоение '$ _' с помощью функции 'readline'? Это означает, что код типа

while (<>) {       # implicitly sets $_
    do_something_with($_);
}

возможно, сломается, если вы переопределите readline.