Какие встроенные модули Perl нельзя переопределить в CORE :: GLOBAL? - PullRequest
13 голосов
/ 09 сентября 2010

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

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

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

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

Что такое полный список?

Ответы [ 4 ]

14 голосов
/ 09 сентября 2010

Любое значение, отрицательное в 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

5 голосов
/ 09 сентября 2010

Функция 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 голосов
/ 09 сентября 2010

Был более ранний вопрос о том, что SO оплакивает сложность насмешек над операторами проверки файлов (-f, -d, -x, ...)

1 голос
/ 23 февраля 2011

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...