1

サブ関数を作成してすべてを1つのファイルに入れることと、パッケージを作成することの違いは何ですか?Perlに関しては、オブジェクト指向は手続き型よりも優れていますか?

基本的に、OOが手続き型よりも優れているシナリオの例を探しています。

ありがとう!

4

2 に答える 2

5

最初に明確にするために、手続き型と OO の違いは、すべてのコードを 1 つのファイルに入れることと、個別のモジュールに入れることの違いと同じではありません。手続き的に呼び出す関数でいっぱいの個別のモジュールを持つことができます。

オブジェクト指向または手続き型のモジュールを使用することが有利な場合は、コードが再利用される場合、またはそれが単なる大規模なコード ベースである場合です。10 の異なる CGI スクリプトを含む CMS があり、すべて同じことをいくつか (ユーザー セッションの検証など) 行う場合、すべての CGI でコードを書き直すのではなく、そのコードを別のモジュールに入れる方が理にかなっています。そのスクリプトに固有の 20 行の関数の場合は、同じファイルに残します。

OO と手続き型のどちらを使用するかは、何を行っているかによって異なります。最近では、ほとんどの人が OO を好む傾向にあります。コードを論理的に考え、後で管理および更新しやすいように適切な方法でグループ化するのに役立つと感じているので、私は彼らに同意します。

于 2011-03-24T00:01:35.350 に答える
0

できるだけ多くのコードをモジュールに入れるのが好きです。モジュールの優れた点は、Perl のテスト ツール (prove および Test::More) を使用して、単体テストを簡単に作成および管理できることです。したがって、ほとんどすべてのコードがモジュール内にある場合、そのほとんどすべてがテスト可能です。

スクリプトを作成するときは、スクリプト内の構成とコマンド ライン オプションを解析するシン ラッパーを使用するのが好きです (おそらく、Config::Any や Getopt::Long などのモジュールを使用します)。スクリプトにはusageサブルーチンも含まれています。main次に、サブルーチン を追加します。main非常に簡単です:

sub main {
    my $cfg = shift;

    my @collected_data;

    for my $file ( @{ $cfg->{files} ) {
        eval {
            my $fh = get_handle_from_file($file);

            my $xyz_data = parse_xyz_data( $fh );

            push @collected_data, extract_data( $xyz_data, $cfg->{filter} );

            1;
        } or do {
            my $e = $@;
            $e = "an unknown error occurred" unless defined $e;

            warn "Error parsing '$file': $e\n";
        };        
    }

    my %summary_data = summarize_data( @collected_data );

    write_summary( $cfg->{summary_target} );

    return;
}

サポートするサブルーチンのほとんどすべてが、1 つまたは複数のモジュールに存在します。

OOP は、データと動作を関連付ける優れた方法です。これにより、コードが読みやすくなり、煩雑さが軽減されます。

 $foo->eat_something( $sandwich )

よりも理解しやすい:

 eat_something( $sandwich, $likes_salty, $likes_sour, $likes_sweet, $likes_spicy );

余分ながらくたはすべて便利な$fooオブジェクト属性にまとめられており、サブコールを乱雑にすることなく移動します。

もちろん、次のことができます。

eat_something( $foo, $sandwich )

$foo は、味の好みの通常のハッシュです。とにかく、これは基本的に Perl OO が行うことです。呼び出し元 (オブジェクトまたはクラス名) は、各メソッドの最初の引数として渡されます。便利な名前空間、継承、および動的メソッド呼び出しが失われます。3 つのコストのうち、便利な名前空間が最も見落とされます。IMO、継承は過大評価されており、めったに使用しないでください。動的メソッド呼び出しは、ディスパッチ テーブルが便利なのと同じ理由で便利です。

手続き型 Perl で実行できないことで OO Perl で実行できないことはありません。しかし、オブジェクト指向は特定のものを非常に便利にします。

神話上のスクリプトを OO スタイルで書き直して締めくくりましょう (例として、OO について少しやりすぎます)。

サブ メイン { 私の $cfg = シフト;

    my $cd = Data::Collection->new();

    for my $file ( $cfg->files ) {
        eval {

            # skip the step of creating a handle first.  The parsing object
            # can take a file and get a handle or could be passed a handle.               

            my $xyz_parser = File::XYZ::Parse->new( file => $file );

            # The parser returns an XYZ::Data object

            my $xyz_data = $xyz_parser->parse;

            $cd->add_data( $xyz_data->extract_data( $cfg->filter );

            1;
        } or do {
            my $e = $@;
            $e = "an unknown error occurred" unless defined $e;

            warn "Error parsing '$file': $e\n";
        };        
    }

    # Skip the step of separate summarization, since the cd object can check if
    # the summary has been done, and if not generate and cache it as needed.

    $cd->write_summary( $cfg->summary_target );

    return;
}
于 2011-03-24T16:49:02.630 に答える