2011-06-29 16 views
3

私が使用している外部Perlライブラリには、自分のアプリケーション(DBD :: SQLite)で使用しない依存関係(DBD :: mysql)があるので、依存関係はちょうどそこにあるように思っていますそれが「偽物」であれば。依存関係のためにperlモジュールを偽装する方法は?

コンパイルする空のDBD :: mysql.pmモジュールを作成するだけですか、これを行うより簡単な方法はありますか?

答えて

8

ここにはほとんど問題がないと思います。

あなたが依存関係と言えば、外部モジュールは単にrequireまたはuseDBD::mysqlにしようとしていますか?その場合、開発者に、DBIを使用する目的に反するため、明示的に行うべきではないことを、開発者にアドバイスする必要があります。データベースドライバは、DSNに基づいてオンザフライで選択する必要があります。

著者は、彼はそれはあなたがそのパッケージを無効にすることができる、そしてはい、行うには便利か意味のあるものだと思ったので、パッケージ名をINGの単なるuseであると仮定すると、それを行うにはいくつかの方法があります。

提案したとおり、DBD::mysqlパッケージを定義する独自のモジュールDBD/mysql.pmを作成するだけで済みます。

興味がある場合は、他にもできることがいくつかあります。偽のディレクトリとファイルでソースツリーを散らすのではなく、モジュールがロードされたことをPerlに伝えるだけで済みます。 %INCを直接操作することでこれを行うことができます。

このハッシュキーを追加するだけで、問題のあるモジュールのファイルシステムの検索を排除します。これはBEGINブロックにあることに注意してください。外部の著者がuseを行った場合、useステートメントが評価される前にこの値を設定する必要があります。 useの文は、BEGINにラップされたrequireimportに相当します。

外部の作者がパッケージのメソッドを呼び出そうとしていたことを一般的に推測することができます。これらのシンボルが存在しない場合、実行時エラーが発生します。 PerlのAUTOLOADを利用して、このような呼び出しを傍受して正しいことを行うことができます。何が正しいことは、単純にメッセージを記録してからもっと精巧なものに変わることがあります。たとえば、この機能を使用して、すべての呼び出しを監視することによって作成者が導入したカップリングの深さを調べることができます。

package DBD::mysql; 

sub AUTOLOAD { 
    printf(
     "I don't wanna '%s' called from '%s'\n", $AUTOLOAD, caller(0) 
    ); 
} 

package main; # or whereever 

BEGIN { 
    $INC{'DBD/mysql.pm'} = "nothing to see here"; 
} 

DBD::mysql::blah() 

今度は、また、問題のある著者は、クラスのいくつかのオブジェクト指向のインスタンスを作成した場合をカバーしてみましょう、と彼のコードが正しくスタブコード用 を考慮していません。我々は、newであるコンストラクタをスタブし、匿名のハッシュをパッケージ名で祝福します。そうすれば、インスタンス上のメソッドを呼び出すときに のエラーが発生することはありません。

package DBD::mysql; 

sub AUTOLOAD { 
    printf(
     "I don't wanna '%s' called from '%s'\n", $AUTOLOAD, caller(0) 
    ); 
} 

sub new { 
    bless({}, __PACKAGE__) 
} 

package main; # or whereever 

BEGIN { 
    $INC{'DBD/mysql.pm'} = "nothing to see here"; 
} 

my $thing = new DBD::mysql; 

$thing->blah() 
関連する問題