その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

インストールされているモジュールをインストールされていないが如く扱う方法

(2013.7.16 追記)
“インストールされているモジュールをインストールされていないが如く扱う方法”の続き - その手の平は尻もつかめるさ
の方法の方が良いと思いますので、そちらをご覧下さい!!
(追記ここまで)

何を言っているか分からないと思いますが、そういう挙動をさせると便利な場合があります。主にテストとかで。

概要

Foo::Bar というモジュールがマシンに入っているけど、
require Foo::Bar;
された時にそのモジュールを読んでほしくない、という欲求が1日に1回はあると思います。

そういう場合はこう書けば良い

BEGIN {
    *CORE::GLOBAL::require = sub {
        my $file = shift;

        unless ($file =~ m!Foo/Bar\.pm!) {
            CORE::require($file);
        }
    };
}
もしくは、場合によって条件にマッチした時にdie させると良いでしょう。
BEGIN {
    *CORE::GLOBAL::require = sub {
        my $file = shift;

        if ($file =~ m!Foo/Bar\.pm!) {
            die 'Not here...';
        }
        CORE::require($file);
    };
}

簡単ですね!

補足

同じ事を `use` でやろうとしたら駄目でした。


現場からは以上です。

追記

@tokuhirom さんからコメントで頂きましたが、'1' とだけ書かれたダミーのモジュールを設置して、
そこに至るパスを@INC のトップに突っ込んでやるという方法があるようです。

なので、コマンドライン上で
$ mkdir /tmp/dummy/lib/Foo
$ touch /tmp/dummy/lib/Foo/Bar.pm
$ echo 1 > /tmp/dummy/lib/Foo/Bar.pm
として、ダミーのモジュールを作ってやってから、スクリプト側で、
BEGIN {
    unshift @INC, "/tmp/dummy/lib";
}
と書いてやると捗る感じです。
つーか、これだったら普通にuse でもいけるな!!!

@tokuhirom さん、ありがとうございます。