2

私は modulino perl パターンをいじっていましたが、パッケージ名とそれが含まれているファイルだけを知らずにロードしたいと考えています。次のように使用できるものを探しています。

eval {
  my $file = "some-file-name-in-the-hierarchy-unrelated-to-package-name";
  my $module = something($file);
  $module->sub1();
};

ここsomethingが鍵です。いいえrequire、またはuse後でモジュール名が必要になるためです。を読んで名前$fileを解析してから使用する必要がありますか? packageきっともっと良い方法があるかもしれません。perlには常にあります。

4

3 に答える 3

5

どのファイルを管理していますか?プログラムをモジュラーとして作成し、そのファイルをロードしようとしている場合は、ファイルの最後のステートメントでパッケージ名を返すようにします。requireは、真の値を返すことを期待しており、ほとんどのモジュールはを使用します1;。ただし、任意の真の値を使用できます。これはrequireの戻り値になります:

# i_dont_know_whats_inside
package Buster;

__PACKAGE__;

読み込みは簡単です。

my $package = require 'i_dont_know_whats_inside';

print "Package is $package\n";

$package->new( ... );

ロードしているファイルを制御できない場合は、中身を見つけるのはそれほど難しくありません。

my @packages = load_file( 'i_dont_know_whats_inside' );

print "Packages are @packages\n";

sub load_file {
    my $file = shift;
    require Module::Extract::Namespaces;
    my @packages = Module::Extract::Namespaces->from_file( $file );
    my $rc = require $file;
    return @packages;
    }
于 2012-03-24T07:44:16.863 に答える
0

パッケージがわからないということは、読み込みメカニズムによって情報が返されなければならないことを意味するため、 を使用する必要があることを意味しますdo

Usingdoは、シンボル テーブルを使用できないことを意味します。これは、匿名サブを意味します。

次のようなファイルを作成します。

sub foo { ... }
sub bar { ... }

{
   foo => \&foo,
   bar => \&bar,
};

または好き

{
   foo => sub { ... },
   bar => sub { ... },
};

次に使用します

my $table = do '/abs/path/to/file.pl' or die $@;
$table{foo}->();

また

my $table = do 'rel/path/to/file.pl' or die $@;  # Relative to entries in @INC
$table{foo}->();

複数回呼び出すことはできますdoが、毎回ファイルをコンパイルして実行するので避けてください。代わりに、返される値をキャッシュします。

醜い!そして、ファイル名とその中のパッケージとの間に何の関係も望まないからです。Perl の要件を回避しようとすると、醜さが予想されます。この要件を持っていても何の役にも立たないので、削除してください。

代わりに、次のようなファイルを作成する必要があります。

package Some::Package;

sub foo { shift; ... }
sub bar { shift; ... }

1;

呼び出しコードは次のようになります。

my $file= 'Some/Package.pm';
my $pkg = $file;
$file =~ s{\.pm\z}{};
$file =~ s{/}{::}g;

require $file;
$pkg->foo();

Module::PluginFinderも参照してください。

于 2012-03-24T00:26:15.103 に答える
0

のリテラル (および変数) は、require正確にファイル名として解釈されます。

例えば:

$var = "TEST::test";
require $var;

出力:

Can't locate TEST::test in @INC (@INC contains: ...)
             ^^^^^^^^^^ -- not TEST/test.pm!
于 2012-03-24T00:35:31.267 に答える