1

構成ファイルで定義された定数を使用すると問題が発生します。これは私のパッケージです:

package myPackage;
require "APIconfig.pl";
APIconfig::import(APIconfig);

use constant SERVICE_URL => APIconfig::SERVICE_URL();

構成は次のようになります。

package APIconfig;
use constant SERVICE_URL => 'http://api.example.org/blah';
1;

このコードを実行すると、次のエラーが発生します。

Undefined subroutine &APIconfig::SERVICE_URL called at API.pl line 4.

「require」の代わりに「use」を使用することはできません。これは、構成ファイルの名前が .pm であることを想定しており、ネットワーク上の多くのサーバーで .pl と呼ばれているためです。ファイルの名前を変更せずにパッケージを使用するにはどうすればよいですか?

4

3 に答える 3

7

「使用」と「必要」には 2 つの違いがあります。そのうちの 1 つは現在の問題に影響しますが、もう 1 つは影響しません。残念ながら、効果のないものを回避しています。

違いは次のとおりです。

1/ 'use' は import() 関数を呼び出しますが、'require' は呼び出しません。

2/ 'use' はコンパイル時に発生し、'require' は実行時に発生します。

「require」が明示的に呼び出して import() を呼び出さないという事実を回避しています。モジュールはシンボルをエクスポートせず、import() サブルーチンを持たないため、これは効果がありません。

「use」ステートメントが実行時に実行されるという事実を回避していません。問題は、「定数 SERVICE_URL => APIconfig::SERVICE_URL(); を使用する」ことです。コンパイル時に実行され、それまでに「require」が実行されていないため、myPackage は APIconfig について何も知りません。

(厄介でハックな)解決策は、「require」ステートメントを BEGIN ブロックに入れることです-コンパイル時に強制的に実行させます。また、 import() の呼び出しを削除すると実行時エラーが発生するため (サブルーチンがないため)、削除する必要があります。

これを解決するために使用したテスト ファイルは次のとおりです。

$ cat APIconfig.pl 
package APIconfig;
use constant SERVICE_URL => 'http://api.example.org/blah';
1;

$ cat api.pl 
#!/usr/bin/perl

package myPackage;
BEGIN {
  require "APIconfig.pl";
}
# APIconfig::import(APIconfig);

use constant SERVICE_URL => APIconfig::SERVICE_URL();

print SERVICE_URL, "\n";
$ ./api.pl 
http://api.example.org/blah

実際の解決策は、APIconfig を実際のモジュールとして書き直すことです。あなたはそれを知っていることをほのめかしますが、環境問題があなたがこのアプローチをとることを妨げていることをほのめかします。これらの問題を回避し、正しく行うことを強くお勧めします。

于 2010-09-07T11:37:16.087 に答える
2

それはおそらく正しいとは言えません - importpackage にサブルーチンはありませんAPIconfig。完全なパッケージ パスを使用してシンボリック名にアクセスすると、とにかくエクスポート/インポートする必要はありません。

require解決策は、コンパイル時に実行することuse constantです。これは機能します:

package myPackage;
BEGIN {
    require "APIconfig.pl";
}

use constant SERVICE_URL => APIconfig::SERVICE_URL();
于 2010-09-07T11:29:15.890 に答える
1

構成ファイルの場合は、コード化しないでください。それについてはMastering Perlに章全体があり、CPAN にはほとんどすべての構成形式で役立つ多くのモジュールがあります。

コードの場合は、 use を使用できるようにモジュールにしてみませんか。モジュールは、別のプログラム内での制御と操作が非常に簡単です。

最も簡単な解決策は、潮に逆らって泳がないことです。:)

それを超えて、使用は次と同じです。

 BEGIN {
      require Module;
      Module->import;
      }

ファイル名とそれが定義する名前空間で同じことを行うだけです (ファイル内のコードがモジュールのように見える限り):

 BEGIN {
      require "file.pl";  # defines SomeNamespace
      SomeNamespace->import;
      }
于 2010-09-07T20:32:11.400 に答える