Какие встроенные модули 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";
}
Ответ 3
Был более ранний вопрос о том, что SO оплакивает трудность издеваться над операторами filetest (-f
, -d
, -x
,...)
Ответ 4
Функция readline(HANDLE)
(и эквивалентный оператор ввода/вывода <HANDLE>
) может быть издеваема, но ее поведение авто- присваивая $_
при использовании как
while (<HANDLE>) { ... # equivalent to while (defined($_=readline(HANDLE)))
быть не может. См. Комментарий к hobbs в Как я могу получить автоматическое присвоение '$ _' с помощью функции 'readline'? Это означает, что код типа
while (<>) { # implicitly sets $_
do_something_with($_);
}
возможно, сломается, если вы переопределите readline
.