AUTOLOADは、パッケージ内の存在しないメソッドや関数の呼び出しを動的に処理することを可能にします。これは、プロキシオブジェクトの作成、動的生成されたメソッド(ORM)、遅延ローディングのロジックの導入などに便利です。
AUTOLOADの使用例:package MyAuto; sub AUTOLOAD { our $AUTOLOAD; my ($self, @args) = @_; my ($method) = $AUTOLOAD =~ /::(\w+)$/; print "呼び出されたメソッド: $method、引数: @args "; } package main; my $obj = bless {}, 'MyAuto'; $obj->any_method(1,2,3); # AUTOLOADが呼び出される
newやDESTROYメソッドの呼び出しをキャッチできない。質問: 存在しないコンストラクタnewを呼び出そうとした場合、AUTOLOADは呼び出されるのか?
回答: いいえ。Perlはnewコンストラクタをパッケージ内で直接探し、見つからなかった場合にAUTOLOADを呼び出しません。AUTOLOADは通常のメソッドの呼び出しの際のみ呼び出され、Class->new()を介してオブジェクトを作成しようとする場合には呼び出されません。
package Foo; sub AUTOLOAD { print "AUTOLOAD! "; } # $obj = Foo->new(); # エラー: Can't locate object method "new" ...
物語 暗号サービスでは、AUTOLOADを通じて多くの単調なメソッドのプロキシを実装しました。ある日、
DESTROYメソッドの処理を忘れ、オブジェクトのファイナライゼーション中に無限再帰呼び出しが発生し、スクリプトがクラッシュしました。
物語 ORMでは、フィールドへのアクセスのマジックのためにAUTOLOADを使用しましたが、メソッドが本当に存在しない場合の適切な値の返却を実装しませんでした。そのため、Perlは「Can't locate...」の代わりに混乱したメッセージを出力し、バグは本番環境でのみ現れました。
物語 リファクタリング中に実際のメソッドの一部を削除したため、すべての呼び出しがAUTOLOAD経由で行われました。その結果、大規模なタスクのパフォーマンスが急落しました(数百万のオブジェクトの配列の処理がリファクタリング前の10〜15倍の時間がかかるようになりました)。