1

Unfortunately, I'm a totally noob when it comes to creating packages, exporting, etc in Perl. I tried reading some of the modules and often found myself dozing off from the long chapters. It would be helpful if I can find what I need to understand in just one simple webpage without the need to scroll down. :P

Basically I have two modules, A & B, and A will use some function off from B and B will use some functions off from A. I get a tons of warning about function redefined when I try to compile via perl -c.

これを適切に行う方法はありますか?それとも私の設計は遅れていますか?もしそうなら、より良い方法は何でしょうか?私がこれを行った理由として、他のモジュール関数をこのモジュールにコピーして貼り付けて名前を変更するのを避けるためです。

4

3 に答える 3

12

循環依存関係を持つことは、あまり良い習慣ではありません。A が B に依存し、A が C に依存し、B が C に依存するように、何かを 3 番目のモジュールに因数分解することをお勧めします。

于 2009-02-24T04:07:06.043 に答える
6

だから...共通コードを別のモジュールに分解するという提案は良いものです。ただし、モジュールに *.pl という名前を付けたりrequire、特定のパス名を -ing してモジュールをロードしたりしないでください (のようにrequire "../lib/foo.pl";)。(たとえば、「..」と言うと、スクリプトは毎回同じ作業ディレクトリから実行されることに依存します。そのため、スクリプトを として実行すると機能する可能性がありますが、 として実行するとperl foo.pl機能しませんperl YourApp/foo.pl。つまり、一般的には良くありません。)

あなたのアプリが YourApp と呼ばれているとしましょう。ディレクトリに存在するモジュールのセットとしてアプリケーションを構築する必要がありますlib/。たとえば、これは「Foo」モジュールです。そのファイル名はlib/YourApp/Foo.pm.

package YourApp::Foo;
use strict;

sub do_something {
    # code goes here
}

ここで、「Foo」に依存する「Bar」というモジュールがあるとします。あなたはただ作っlib/YourApp/Bar.pmて言う:

package YourApp::Bar;
use strict;
use YourApp::Foo;

sub do_something_else {
    return YourApp::Foo::do_something() + 1;
}

(高度な演習として、Sub::ExporterまたはExporterを使用して、使用use YourApp::Fooするパッケージの名前空間にサブルーチンをインストールすることができます。これにより、YourApp::Foo::すべての前に記述する必要がなくなります。)

とにかく、このようにアプリ全体を構築します。機能の論理的な部分は、モジュール (またはクラス) にまとめてグループ化する必要があります。

このすべてを実行するには、次のような小さなスクリプトを作成します (これらを に入れてbin/いるので、 と呼びましょうbin/yourapp.pl)。

 #!/usr/bin/env perl

 use strict;
 use warnings;
 use feature ':5.10';

 use FindBin qw($Bin);
 use lib "$Bin/../lib";

 use YourApp;
 YourApp::run(@ARGV);

ここで重要なのは、アプリの実行を開始するための小さなボイラープレートを除いて、コードがモジュールの外側にないことです。これは保守が簡単で、さらに重要なことに、自動化されたテストを簡単に作成できます。コマンドラインから何かを実行する代わりに、いくつかの値を指定して関数を呼び出すことができます。

とにかく、これはおそらく今話題から外れています。でも、知ることは大事だと思います。

于 2009-02-24T04:38:31.553 に答える
2

簡単な答えは、コンパイル モジュールを perl -c でテストしないことです...代わりに perl -e'use Module' または perl -e0 -MModule を使用してください。perl -c は、モジュールではなく、スクリプトのテスト コンパイルを行うように設計されています。あなたのいずれかでそれを実行すると、

モジュールを再帰的に使用する場合の重要なポイントは、外部参照されるものを早期にセットアップすることです。通常、これは少なくとも @ISA をコンパイル時の構成要素 (BEGIN{} または「use parent」または非推奨の「use base」を介して) に設定し、@EXPORT とフレンドを BEGIN{} に設定することを意味します。

基本的な問題は、モジュール Foo がモジュール Bar (Foo を使用する) を使用する場合、Bar が完全にコンパイルされてメインライン コードが実行されるまで、Foo のコンパイルがその時点で停止することです。Foo Bar のコンパイルとメインライン コードの実行に必要な部分が何であれ、そこに答えがあることを確認します。

(多くの場合、機能をより多くのモジュールに賢明に分離し、再帰を中断することができます。これは何よりも優れています。)

于 2009-02-24T04:58:34.190 に答える