2

さまざまな関数をエクスポートするPerlモジュールがいくつかあります。(新しいモジュールで@EXPORTを数年間使用していませんが、古いスクリプトとの互換性のために@EXPORTを保持しています。)

一貫した命名ポリシーに変更するためにいくつかの関数とメソッドの名前を変更し、次のような行のリストを追加すると思いました

*directory_error      = *directoryError;

モジュールの最後で、古い名前を新しい名前にエイリアスします。

これは、古い名前がエクスポートされ、呼び出し元のスクリプトが非修飾名で関数を呼び出す場合を除いて機能します。この場合、サブルーチンが(呼び出し側モジュールに)見つからないことを報告します。

エイリアスが作成されていないときに、エクスポーターがBEGINでリストを準備していることが起こっていると思います。しかし、typeglob割り当てをBEGINブロックに入れてみましたが、それは役に立ちませんでした。

AUTOLOADを試しましたが、もちろん、呼び出し元のコンテキストで名前を使用できるようにはなりません。もちろん、一連のラッパー関数を書くこともできますが、それは面倒です。方法はわかりませんが、ラッパー関数を自動的に生成できる可能性があります。

これを処理するためのきちんとした方法の提案はありますか?

4

3 に答える 3

2

エクスポート

@EXPORT =()を手動で呼び出すと、少し厄介になります。

package Bar;
use strict;
use warnings;

use Sub::Exporter -setup => {
    exports => [qw[ foo ]],
    groups  => {
        default => [qw[ foo ]],
    }
};

sub foo(){

};


1;

使用する:

use strict;
use warnings;
use Bar  foo => { -as-> 'Foo' }; 

Sub :: Exporterは、グループエクスポート、グループ除外、ビルダーメソッドなど、多くのすばらしい機能を実行できます(つまり、エクスポートするサブがどのように機能するかは、渡されたパラメーターによって決定され、サブは他のサブ内で生成されます)。

名前の変更

名前を変更するには、Carp()が呼び出されたときに、それを指すコードを新しいメソッドに移動するように推奨するレガシー関数として機能するセカンダリ関数を使用する方がよい場合があります。これにより、コード全体の一貫性が向上します。

その後、テストで警告が表示されなくなったら、レガシー関数を削除できます。

sub old {  # line 1
   Carp::carp('Legacy function \'old\' called, please move to \'newmethod\' '); 
   goto &newmethod; # this passes @_ literally and hides itself from the stack trace. 
} # line 4

sub newmethod { # line 6
   Carp::cluck('In New Method'); 
   return 5;
} # line 9

print old(), "\n";  # line 11
レガシー関数「old」が呼び出されました。code.plの2行目で「newmethod」に移動してください
    main :: old()がcode.plの11行目で呼び出されました
code.plの7行目の新しいメソッド
    main :: newmethod()がcode.plの11行目で呼び出されました
5

newmethodの警告が、直接呼び出された場合とまったく同じように見えることに注意してください。

于 2009-05-01T17:01:11.610 に答える
1

以下は私のために働きます。これはあなたが説明していることのようです。あなたはどこかで間違いを犯したに違いありません。

メインスクリプト:

use strict;
use warnings;
use Bar;

baz();

モジュール:

package Bar;
use strict;
use warnings;

require Exporter;
our @ISA    = qw(Exporter);
our @EXPORT = qw(baz);

sub Baz { print "Baz() here\n" }

*baz = *Baz;

1;
于 2009-04-29T13:21:26.880 に答える
0

両方の名前を表示するには、両方の名前をエクスポートする必要があります。マイケル・カーマンの答えをベースとして使用すると、

our @EXPORT = qw(Baz baz);

また

our @EXPORT    = qw(Baz);
our @EXPORT_OK = qw(baz);

プログラムでどちらかを呼び出せるようにしたい場合。同じcoderefを指しているからといって、そのcoderefのすべての名前がエクスポートされるとは限りません。

于 2009-04-29T14:06:51.390 に答える