Мне нужно удалить метод из таблицы символов Perl во время выполнения. Я попытался сделать это с помощью undef &Square::area
, который удаляет функцию, но оставляет после себя некоторые следы. В частности, когда вызывается $square->area()
, Perl жалуется, что это «Не ссылка на КОД», а не «Неопределенная подпрограмма и Square :: area called», как я и ожидал.
Вы можете спросить: «Почему это важно? Вы удалили функцию, зачем вы ее вызываете?» Ответ в том, что я не называю это Perl. Square наследуется от Rectangle, и я хочу, чтобы цепочка наследования передавала $square->area
в &Rectangle::area
, но вместо того, чтобы пропустить Square, где метод не существует, а затем перейти в область Rectangle (), вызов метода завершается с сообщением "Not a CODE reference" . "
Как ни странно, это происходит только тогда, когда & 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.
undef &Square::area
удалит подпрограмму? Не атака, просто любопытно ... - person Ether   schedule 13.01.2011undef &mysub;
, но он также работает с полными именами. - person KingPong   schedule 13.01.2011