サブ関数を作成してすべてを1つのファイルに入れることと、パッケージを作成することの違いは何ですか?Perlに関しては、オブジェクト指向は手続き型よりも優れていますか?
基本的に、OOが手続き型よりも優れているシナリオの例を探しています。
ありがとう!
サブ関数を作成してすべてを1つのファイルに入れることと、パッケージを作成することの違いは何ですか?Perlに関しては、オブジェクト指向は手続き型よりも優れていますか?
基本的に、OOが手続き型よりも優れているシナリオの例を探しています。
ありがとう!
最初に明確にするために、手続き型と OO の違いは、すべてのコードを 1 つのファイルに入れることと、個別のモジュールに入れることの違いと同じではありません。手続き的に呼び出す関数でいっぱいの個別のモジュールを持つことができます。
オブジェクト指向または手続き型のモジュールを使用することが有利な場合は、コードが再利用される場合、またはそれが単なる大規模なコード ベースである場合です。10 の異なる CGI スクリプトを含む CMS があり、すべて同じことをいくつか (ユーザー セッションの検証など) 行う場合、すべての CGI でコードを書き直すのではなく、そのコードを別のモジュールに入れる方が理にかなっています。そのスクリプトに固有の 20 行の関数の場合は、同じファイルに残します。
OO と手続き型のどちらを使用するかは、何を行っているかによって異なります。最近では、ほとんどの人が OO を好む傾向にあります。コードを論理的に考え、後で管理および更新しやすいように適切な方法でグループ化するのに役立つと感じているので、私は彼らに同意します。
できるだけ多くのコードをモジュールに入れるのが好きです。モジュールの優れた点は、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;
}