我需要在運行時從Perl符號表中刪除一個方法。我試圖用undef &Square::area
這樣做,它刪除了該功能,但留下了一些痕跡。具體來說,當調用$square->area()
時,Perl會抱怨它不是「代碼引用」而不是「未定義的子例程& Square :: area called」,這正是我所期望的。爲什麼這個Perl產生「不是一個CODE引用?」
您可能會問:「爲什麼這麼重要?您刪除了該功能,您爲什麼要這樣做?」答案是我不叫它,Perl是。 Square從Rectangle繼承,我希望繼承鏈通過$square->area
到&Rectangle::area
,但不是跳過方法不存在的Square,然後進入Rectangle的區域(),而是在方法調用中使用「Not a CODE reference 「。
奇怪的是,這似乎只發生在& Square :: area由typeglob賦值(例如*area = sub {...}
)定義。如果使用標準sub area {}
方法定義函數,則代碼按預期工作。
另外有趣的是,如預期的那樣定義整個glob作品。只是沒有定義子程序本身。
下面是說明了症狀很短的例子,並用正確的行爲形成鮮明對比:
#!/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 [email protected];
# Undefined subroutine &main::hi called (as expected)
sub hi { "Hi!\n" }
undef &hi;
eval { hi };
print [email protected];
# Undefined subroutine &main::hello called (as expected)
sub hello; *hello = sub { "Hello!\n" };
undef *hello;
eval { hello };
print [email protected];
更新:因爲我已經解決了使用套票:藏匿處(感謝@Ether)這個問題,但我米仍然爲什麼它首先發生困惑。 perldoc perlmod
說:
package main;
sub Some_package::foo { ... } # &foo defined in Some_package
這僅僅是在編譯時一個類型團賦值速記:
BEGIN { *Some_package::foo = sub { ... } }
但看來,它不是」 t 只是速記,因爲這兩者在定義函數後會導致不同的行爲。如果有人能告訴我這是(1)不正確的文檔,(2)perl錯誤還是(3)PEBCAK,我會很感激。
你從哪裏得到'undef&Square :: area`會刪除子程序的想法?不是攻擊,只是好奇... – Ether 2011-01-12 22:14:29
從`perldoc -f undef`。他們給出的例子是`undef &mysub;`,但它也適用於限定名稱。 – KingPong 2011-01-12 22:26:04