Мне нужно удалить метод из таблицы символов Perl во время выполнения.Я попытался сделать это, используя undef &Square::area
, который удаляет функцию, но оставляет некоторые следы.В частности, когда вызывается $square->area()
, Perl жалуется, что это «Не ссылка на код» вместо «Неопределенная подпрограмма и квадрат :: область под названием», чего я и ожидаю.
Вы можете спросить: «Почемуэто имеет значение? Вы удалили функцию, почему вы бы назвали ее? "Ответ в том, что я не называю это, Perl.Square наследует от Rectangle, и я хочу, чтобы цепочка наследования передавала $square->area
до &Rectangle::area
, но вместо пропуска Square, где метод не существует, а затем падения в область Rectangle (), вызов метода умирает с помощью "Не ссылка на CODE. "
Как ни странно, это происходит только тогда, когда & Square :: area была определена присваиванием typeglob (например, *area = sub {...}
).Если функция определена с использованием стандартного подхода sub area {}
, код работает, как и ожидалось.
Также интересно, что неопределенный весь глобус работает, как и ожидалось.Просто не отменяйте определение самой подпрограммы.
Вот краткий пример, который иллюстрирует симптом и отличается от правильного поведения:
#!/usr/bin/env perl
use strict;
use warnings;
# This generates "Not a CODE reference". Why?
sub howdy; *howdy = sub { "Howdy!\n" };
undef &howdy;
eval { howdy };
print $@;
# Undefined subroutine &main::hi called (as expected)
sub hi { "Hi!\n" }
undef &hi;
eval { hi };
print $@;
# Undefined subroutine &main::hello called (as expected)
sub hello; *hello = sub { "Hello!\n" };
undef *hello;
eval { hello };
print $@;
Обновление : с тех пор я решил эту проблемупроблема с использованием Package :: Stash (спасибо @Ether), но я все еще не понимаю, почему это происходит в первую очередь.perldoc perlmod
говорит:
package main;
sub Some_package::foo { ... } # &foo defined in Some_package
Это просто сокращение для назначения typeglob во время компиляции:
BEGIN { *Some_package::foo = sub { ... } }
Но похоже, что это не просто стенография, потому что эти два вызывают различное поведение после отмены определения функции.Буду признателен, если кто-нибудь скажет мне, является ли это случаем (1) неправильных документов, (2) ошибки в Perl или (3) PEBCAK.