Acme::Seclusion::JP

tag perl acme

こんにちは。Acme Track 2回目のhide_o_55です。

今回紹介させて頂くのは、Acme::Seclusion::JPです。
このモジュールを使用すると江戸時代のような鎖国状態を実現できます。
具体的には日本、中国、韓国、オランダ*1以外のモジュールは使用できなくなります。

use Acme::Seclusion::JP;
use Moose;

上記のようにMooseを使うと標準エラー出力にエラーメッセージを出力しexitします。作者が日本人のMouseなら通常動作をします。

この動作をどのようにして実現しているかというと、http://perldoc.perl.org/functions/require.html にも書かれている、@INCに[コードリファレンス|オブジェクト]を入れるテクニックを使用しています。@INCにコードリファレンスが含まれている時にモジュールをロードしようとすると、そのコードリファレンスが実行されます(オブジェクトの場合はINCメソッドが実行されます)。

この機能を利用して、モジュールのロードをフックし、モジュール名からモジュールの作者情報を検索します。そのあと、Acme::CPANAuthorsを利用して、作者がAcme::CPANAuthors::Japanese、Acme::CPANAuthors::Chainese、Acme::CPANAuthors::Korean、Acme::CPANAuthors::Dutchに含まれるか判定し、含まれなければexitします。(ちなみにAcme::CPANAuthors::Dutchのリストは空です。理由はPODを読んでみてください)

なお、以下のように "-complete" オプションを指定すると完全鎖国モードになり、日本のモジュール以外は使用できなくなります。*2

use Acme::Seclusion::JP '-complete';

「舶来品は使わん!」という頑固な攘夷派の方にオススメです。

今回は、@INCによるモジュールロードのフックでアホなことをしていますが、以下のようにモジュールをロードした際に暗黙的にロードされるモジュールをトレースして、遅延ロード化を検討したりとか、わりと実用的なこともできます。

perl -MPerl6::Say -e 'BEGIN{unshift @INC,sub{ say join "\t=>\t",(caller)[0],do{(my $mod = $_[1]) =~ s!/!::!g;$mod =~ m!(.+)\.pm!}}}use MyModule;'
*1: 最初はポルトガルも入れてましたがよく考えたら所謂「鎖国体制完成」時にはポルトガルとも国交が断絶してたので外しました
*2: コアモジュールを除く