ROUTE 3390

備忘録的な用途で書いていますが、どなたかの役に立つ事があれば嬉しいです。

Exporter.pmの役割を知ったのでメモ

perl文字コードを扱う時に使用するモジュールといえばEncode.pmですよね。
CPANはこちら


SYNOPSISを見ると下記のようにuseしていますね。

use Encode qw(decode encode);
$characters = decode('UTF-8', $octets,     Encode::FB_CROAK);
$octets     = encode('UTF-8', $characters, Encode::FB_CROAK);

decodeメソッドとencodeメソッドを使いたい場合は、このようにuseします。


こうした場合はencodeメソッドは使えません。

use Encode qw(decode);


でもこれならdecodeメソッドもencodeメソッドも使えます。

use Encode;


内部ではどうなってるの?


Encode.pmのソースを見てみると、なにやらExporter.pmというモジュールで
そのあたりの処理をやっているみたい。
で、Exporter.pmが何をしてくれるのかというと
「関数をモジュールに紐づける」という機能でした。

@EXPORTという配列に関数名を入れておくと、
useしたモジュールに関数を紐づけてくれるんです。

要するに

use Encode;
Encode::encode('utf8', 'test');

ではなくて

use Encode;
encode('utf8', 'test);

と記述出来るのは、
Encode.pmのソースで下記のような配列を宣言しているからです。

our @EXPORT = qw(
  decode  decode_utf8  encode  encode_utf8 str2bytes bytes2str
  encodings  find_encoding clone_encoding
);

確かに@EXPORT配列にencodeが入っていますね。

注意が必要なのは@EXPORTに入っていればuseした時に紐づけられますが、
useした時に引数を指定した場合には、指定した関数しか紐づけられません。
上でも書きましたが

use Encode qw(decode);
encode('utf8', 'test);

これはエラーになります。


@EXPORTの他に@EXPORT_OKというのもあります。
こちらはuseの際に引数で指定しないと絶対に使えない関数名を入れておきます。


Exporter.pmの動作

1. 引数が無かった場合@EXPORTに入った関数名を紐づける。
2. 引数で関数が指定された場合、@EXPORTと@EXPORT_OKの中にある関数であれば紐づける。


その他にも%EXPORT_TAGSというのもあります。
これは紐づけたい関数が沢山あるときに使うもので
Encode.pmでは下記のようになっています。

our %EXPORT_TAGS = (
    all          => [ @EXPORT,    @EXPORT_OK ],
    default      => [ @EXPORT ],
    fallbacks    => [ @FB_CONSTS ],
    fallback_all => [ @FB_CONSTS, @FB_FLAGS ],
);

これはuseするときに下記のように「:タグ名」とすることで、たくさんの関数を紐づけたい時に使います。

use Encode(:all);


Archive::Zipモジュールはこの方法がSYNOPSISに書かれていたりしますね。


useしたことで、使わない関数までも紐づけられるのを避けられるよう考慮されているなんて
Exporter.pm素晴らしい!