実行時にPerlシンボルテーブルからメソッドを削除する必要があります。私はundef &Square::area
を使用してこれを実行しようとしましたが、これは機能を削除しますが、いくつかのトレースが残っています。具体的には、$square->area()
が呼び出されたとき、Perlは「未定義サブルーチン& Square :: area」の代わりに「Not a CODE reference」であると文句を言います。なぜこのPerlは "Not a CODE reference?"を生成しますか?
「なぜ重要なのですか?あなたはその機能を削除しました。なぜそれを呼び出すのですか?答えは私がそれを呼んでいないということです、Perlはです。 SquareはRectangleを継承し、継承チェーンはから&Rectangle::area
に渡しますが、メソッドが存在しない場合はSquareをスキップし、Rectangleのarea()に落ちるのではなく、メソッド呼び出しが「Not a CODE reference "
奇妙なことに、& Square :: areaがタイプグロブの割り当て(例:*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 [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 { ... } }
しかし、それはにISNことが表示されます」 t ちょうどは、関数の定義を解除した後に2つの動作が異なるため、省略されています。私はこれが(1)間違ったドキュメント、(2)perlのバグ、(3)PEBCAKのいずれかのケースかどうかを誰かが教えていただければ幸いです。
あなたは 'undef&Square :: area'がサブルーチンを削除するという考えをどこから得ましたか?攻撃ではなく、ちょうど興味深い。 – Ether
'perldoc -f undef'から。彼らが与えた例は 'undef &mysub;'ですが、修飾名でも動作します。 – KingPong
「あなたが質問するかもしれません。なぜあなたは&Square :: areaを最初に定義しましたか?なぜあなたはスーパークラスに委譲するために&Square :: areaを定義しませんか? –