2

モジュールに変換し、現在 CPAN モジュールで行っているように、Perl スクリプトからその関数を呼び出したいスクリプトがあります。私の質問は、他の人がモジュールをどのように設計するかということです。私はモジュールを書いたことがないので、どのように進めるかを知りたいです。現在書かれているスクリプトは、次のことを行います。

1) am in house モジュールを使用してデータベースへのロギングをセットアップします 2) DBI を使用してデータベースへの接続を確立します 3) Net::SFTP:Foreign を使用してリモートサーバーからファイルを取得します 4) 各ファイルでユーザーを処理しますデータをDBに追加します

スクリプトは現在、Getopt::Long を使用してデフォルトをオーバーライドするコマンド ライン オプションを使用します。

各ファイルはパイプで区切られたユーザー データのコレクションであり、ユーザーが LDAP ディレクトリにエントリを持っている場合、db に入力される ~4000 行です。

さらに要点: モジュールをどのように設計すればよいでしょうか? 私のスクリプトが現在実行しているすべてのことをモジュールに移動する必要がありますか、それともスクリプトに残すのが最善の方法がありますか? たとえば、モジュールを設計することを考えていたので、次のように呼び出されます。

use MyModule;

$obj = MyModule->new; // possibly pass some arguments

$obj->setupLogging;

$obj->connectToDB;

$obj->fetchFiles;

$obj->processUsers;

そうすればスクリプトはきれいに保たれますが、これはモジュールにとって最良のアイデアでしょうか? スクリプトでファイルを取得し、パスをモジュールに渡して処理することを考えていました。ありがとう

4

2 に答える 2

2

最も有用な質問は、「このコードのうち、複数のスクリプトで使用できるものは何か?」という質問だと思います。確かにすべてはそうではありません。私はめったに perl モジュールを作成しませんが、同じサブルーチンを 2 回以上書いていることに気がつくまでは。

その段階で、よく定義された責任を持つモジュールに属するものをパターン (実際には 4 つの意味のギャングではありません) が示唆し始めるのに十分なコードが収集されるまで、"Utility.pm" と呼ばれるものにダンプします。

もう 1 つは、モジュールがオブジェクト クラスを表すのか、それともライブラリ サブルーチンのコレクションになるのかということです。

あなたの例では、外部モジュールに属するロギングとデータベース接続管理(DBIを使用する可能性が高いですが)を見ることができました。

しかし、すべてをそこに入れると、"MyModule::DoStuff" を呼び出す 5 行のスクリプトが残るだけで、あまり役に立ちません。

ほとんどの時間 ;)

于 2012-05-08T14:38:56.423 に答える
1

「これはモジュールにとって最良のアイデアですか?私は、スクリプトにファイルを取得させ、処理のためにモジュールへのパスを渡すことを考えていました。」

私にはまともなデザインに見えます。また、モジュールにパス (または URL) をハードコードするべきではないことにも同意しますが、「スクリプトでファイルを取得し、処理のためにパスをモジュールに渡す」という意味に少し混乱しています。 、スクリプトはそれらをディスクに書き込みますか? なぜそれをするのですか?代わりに、それが理にかなっている場合はfetchFile(URL)、単一のファイルを取得し、への送信に適した参照/ハンドル/オブジェクトを返す必要がprocessUsersあるため、ロジックは次のようになります。

my @FileUrls = ( ... );

foreach (@FileUrls) {
    my $file = $obj->fetchFile($_);
    $obj->processUsers($file);
}

ただし、fetchFile の目的が生のテキストを取得することだけである場合は、それをデータベース クラス (スクリプトの一部または別のモジュール) から独立した関数にすることをお勧めします。

ディスクに書き込みたい理由が、一度にファイル全体をメモリにロードしたくないということである場合、ファイルを取得するための 1 種類のオブジェクトを持つことができるように、ファイルのチャンクを処理するようにすべてを調整することができます。ソケットを介して、別の種類のオブジェクトに読み取られるときにチャンクを出力します (データベース 1 に追加するプロセス)。その場合:

my $db = DBmodule->new(...);
my $netfiles = NetworkFileReader->new(...)

foreach (@FileUrls) {
    $netfiles->connect($_);
    $db->newfile();  # initialize/reset
    while (my $chunk = $netfiles->more()) {
        $db->process($chunk);
    }
    $db->complete();
    $netfiles->close();
}

または、より適切であり、一般的な目的を果たす可能性が低いと思われる場合は、チャンクの読み取りを db クラスに組み込みます。

于 2012-05-08T15:21:32.587 に答える