こんにちは。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;'