2012-01-09 17 views
0

マイプロジェクトの構造体:perlでプラグインファイルを動的に読み込む方法は?

Test.pm 
Plugins/Plugin1.pm 
Plugins/Plugin2.pm 

test.pmは、次のようになります。たとえば、同じAPIを

sub new{ 
#how to dynamic load plugins? 

plugin1、plugs2提供、sub run {#...}

perlスクリプトは次のようになります。

my $test=Test->new("Plugin1"); 
$test->run ;#should call Plugin1->run 

test.pmのプラグインを動的に読み込む方法は?

私を助ける良いフレームワークはありますか?

ありがとうございました。

+0

http://stackoverflow.com/questions/2025261/how-can-i-find-all-the-packages-that-inherit-from-a-package-in-perl http://stackoverflow.com/質問/ 2478009/plugin-object-with-pluginsとは何ですか?http://stackoverflow.com/questions/4815432/what-is-the-best-option-for-building-a-plugin-system -for-a-moose-application http://stackoverflow.com/questions/8301959/dynamically-loading-perl-modules – daxim

答えて

2

あなたはより完全な答えたい場合:

  1. How can I conditionally import a package in Perl?

  2. In Perl, is it better to use a module than to require a file?

  3. まず、見てみましょう

最初のリンクでの質問への答えはあなたが望むものである:

eval { 
    require Plugin1; 
    Plugin1->import(); 
}; 
if ([email protected]) { 
    warn "Error including Foobar: [email protected]"; 
} 

しかし、あなたの場合のために、あなたのモジュール名は、あなたがする必要がある文字列である可能性があるため:

eval { 
    my $module_name = 'Plugin1.pm'; 
    require $module_name; 
    $module_name =~ s/\.pm//; 
    $module_name->import(); 
}; 
if ([email protected]) { 
    # handle error here 
} 

importは、既にエクスポートされたサブルーチン、Plugin1を使用することができます。例えばfunc()Plugin1でエクスポートされている場合は、この全体のことは、あなたのTest.pmモジュール内のBEGIN {};で優れて入れてfunc()ないPlugin1::func()

でそれを呼び出すことができます。そうしないとimport()が有効にならないことがあります。

+0

また、 'Module :: Load'を見てください。それはあなたと、おそらく他の時間とエネルギーを節約します。 –

+0

これは 'Path/Plugin1.pm'が失敗すると失敗します。 –

2

requireは、モジュールをロードします:

require "Plugins/Plugin1.pm"; 

は、これは失敗する可能性がありますので、あなたは、エラーを処理する必要があります。

useはコンパイル時です。

4
eval { 
    require $plugin; 
} 
if([email protected]) # try another one or report error or whatever ... 

これは基本的に必要なものです。モジュールを必要とするほど複雑ではありません。モジュールのコンパイル中に早めに行う必要がある場合は、BEGIN {}ブロックにラップすることができます。

+0

これは正しいことではありません。 '$ plugin'がファイル名ではない場合、これは失敗します。より良いアプローチです: 'eval" require $ plugin; 1 "' –

2

Module::PluginFinder

use Module::PluginFinder qw(); 

my $finder = Module::PluginFinder->new(
    search_path => 'Plugins', 
); 

my $test = $finder->construct("Plugin1"); 
$test->run(); 
1

にエラーに特別な何かをしたい場合:

sub new { 
    my $class = shift; 
    ...; 
    for my $plugin (@_){ 
    if(eval "require $plugin"){ 
     # successful 
     ...; 
    }else{ 
     # unsuccessful 
     die [email protected]; 
    } 
    } 
    ...; 
} 

は、そうでない場合だけ使用します。

sub new { 
    my $class = shift; 
    ...; 
    for my $plugin (@_){ 
    eval "require $plugin" or die [email protected]; 
    # successful 
    ...; 
    } 
    ...; 
} 
0

十分なアプローチがある:あなたが現代の枠組みの中に見ることができ

eval "require $plugin_class; 1" or die "Error"; 

MojoliciousMojo::Loaderどのようにそれを確認してください。

関連する問題