ヘッダー付きのわずかに異なる形式のcsvファイルを解析し、ファイル内のデータを表すオブジェクトのリストを返すMooseクラスを作成しようとしています。コードの簡略版は次のとおりです。
package MyParser;
use Moose;
use namespace::autoclean;
use Text::CSV_XS;
use MyData; #class that represents data for each row of csv
has 'type' => ( is => 'ro', isa => 'Str', required => 1 );
sub get_data {
my($self, $file) = @_;
open my $fh, '<', $file || die "Can't open file $!";
my $csv = Text::CSV_XS->new;
$csv->column_names($csv->getline($fh));
my @data;
if ($self->type eq 'filetype1'){
while (my $row = $csv->getline_hr($fh)){
push @data, MyData->new(field1 => $row->{col1},
field2 => $row->{col2},
field3 => $row->{col3},
);
}
}
elsif ($self->type eq 'filetype2'){
while (my $row = $csv->getline_hr($fh)){
push @data, MyData->new(field1 => $row->{colA},
field3 => _someFunction($row->{colB}), # _someFunction does some manipulation with the data
field5 => $row->{colC},
);
}
}
elsif ($self->type eq 'filetype3'){
while (my $row = $csv->getline_hr($fh)){
push @data, MyData->new(field1 => $row->{column_1},
field2 => _someOtherFunction($row->{column_2}), # _someOtherFunction does some manipulation with the data
field3 => $row->{column_3},
field4 => $row->{column_4},
field5 => $row->{column_5},
);
}
}
close $fh;
return \@data;
}
__PACKAGE__->meta->make_immutable;
1;
クラス MyData は単純なデータ構造であり、一部の属性にはデフォルトの属性があります (したがって、上記とは異なる初期化があります)。一部の csv ファイル タイプには、ファイル タイプに依存する何らかの操作が必要な列 (たとえば、単純な式に入れる必要がある数値) もあります。この MyData はメイン スクリプトに返され、Oracle のテーブルに挿入されます。
私の目的は、MyParser が、必要に応じて拡張できる特定の指定されたタイプの csv ファイルを処理し、get_data メソッドから MyData のリストを返すことです。ただし、現在の方法は、私が解決しようとしているものに対するエレガントでシンプルなソリューションのようには見えません。
だから私が尋ねたい/コメントしたいのは:
これを解決するためのより良い/より簡単な方法はありますか (おそらく Factory パターンなどの設計パターンを介して)?
それとも、単純に見えて複雑な問題を解決しようとしているのだろうか?