1

perlmonks からの相互投稿:

$work にある大雑把で古いコードをクリーンアップする必要があります。新しいモジュールを作成する前に、適切なものを誰かが知っている場合は、既存のモジュールを使用したいと思います。

実行時にファイルを解析して、一連のデータに対してどのような処理を行う必要があるかを判断します。

もし私がモジュールを書くとしたら、もっと一般的に (DBI 固有ではない) しようとしますが、私の正確なユースケースは次のとおりです:

SQL ファイルを読み取って、データベースに対して実行するクエリを決定しました。上部のコメントを解析し、

  • 列 A には as/// を適用する必要があり、
  • 列 B は、指定された形式の日付のように変換する必要があります。
  • 列 C は一種の tr/// を取得します。
  • さらに、列 D が s/// になるように連鎖させることができ、1 または 2 でない場合は 3 に設定します。

そのため、データベースからフェッチするとき、プログラムはデータを返す前にさまざまな (おそらくスタックされた) 変換を適用します。

現在、コードはひどく大きくて難しい一連の if 句を処理しており、命令の配列を読んだり維持したりするのが非常に困難です。

したがって、私が想像しているのは、おそらくこれらの行を解析し (さらに機能的なインターフェイスを公開し)、適用するプロセッサのリストを積み重ね、渡されたデータに対してそれを実行できるオブジェクトです。

必要に応じて、名前/カテゴリ オプションを指定して、1 つのオブジェクトを動的に使用して、特定の名前/カテゴリ/列のプロセッサのみをスタックすることができます。

伝統的に考案された例:

$obj = $module->new();  
$obj->parse("-- greeting:gsub: /hi/hello"); # don't say "hi"  
$obj->parse("-- numbers:gsub: /\D//"); # digits only  
$obj->parse("-- numbers:exchange: 1,2,3 one,two,three"); # then spell out the numbers  
$obj->parse("-- when:date: %Y-%m-%d 08:00:00"); # format like a date, force to 8am  
$obj->stack(action => 'gsub', name => 'when', format => '/1995/1996/'); # my company does not recognize the year 1995.  

$cleaned = $obj->apply({greeting => "good morning", numbers => "t2", when => "2010116"});  

各プロセッサ (gsub、date、exchange) は個別のサブルーチンになります。プラグインは、名前でさらに追加するように定義できます。

$obj->define("chew", \&CookieMonster::chew);  
$obj->parse("column:chew: 3x"); # chew the column 3 times  

当然の最初の質問は、私が使用できるモジュールを知っている人はいますか? これまでに見つけることができたのは [mod://Hash::Transform] だけですが、実行時にどの処理を動的に行うかを決定するため、常に「複雑な」オプションを使用することになります。パーサー/スタッカーをビルドする必要があります。

私が利用/ラップしたい同様のモジュール、またはわずかに関連するモジュールを知っている人はいますか?

公共の消費のための一般的なものが何もない場合(確かに私のものだけが暗いパンではありません)、覚えておくべきことやインターフェイスの提案、またはDBIからのデータの戻り値を変更する以外の他の可能な用途について、誰かアドバイスがありますか?テキスト::CSVなど?

新しいモジュールを書くことになった場合、名前空間の提案はありますか? Data:: の下の何かがおそらく適切だと思います... 私のユースケースは PAM を思い起こさせるので、「プラグ可能」という言葉が頭に浮かび続けますが、本当に良いアイデアはありません...

  • データ::プロセッサ::プラグイン可能?
  • Data::Munging::Configurable ?
  • 私::噛む::データ ?
4

3 に答える 3

0

最初に、可能であれば SQL クエリにできるだけ多くの書式を配置するようにします。日付形式などは、間違いなく SQL で処理する必要があります。

私の頭の中で、私が知っていて、あなたの目的に使用できるモジュールはData::FormValidatorです。これは主に CGI パラメーターの検証を目的としていますが、必要な機能を備えています。つまり、フィルターと制約を定義し、それらをさまざまな方法で連鎖させることができます。目的のモジュールが他にないという意味ではありません。わかりません。

または、すでにほのめかしたことを実行できます。ある種のコマンド クラスを定義し、それらをさまざまなデータ入力にチェーンすることができます。私はこれらの行に沿って何かをします:

package MyDataProcessor;

use Moose;
has 'Transformations' => (
    traits => ['Array'],
    is => 'rw',
    isa => 'ArrayRef[MyTransformer]',
    handles => {
        add_transformer => 'push',
    }
);

has 'input' => (is => 'rw', isa => 'Str');

sub apply_transforms {  }


package MyRegexTransformer;

use Moose;

extends 'MyTransformer';

has 'Regex' => (is => 'rw', isa => 'Str');
has 'Replacement' => (is => 'rw', isa => 'Str');

sub transform {  }

# some other transformers
#

# somewhere else
#
#

my $processor = MyDataProcessor->new(input => 'Hello transform me');

my $tr = MyRegexTransformer->new(Regex => 'Hello', Replacement => 'Hi');

$processor->add_transformer($tr);

#...

$processor->apply_transforms;
于 2010-11-17T19:24:25.353 に答える
0

みんなの考えに感謝します。

短いバージョン: いくつかの既存のモジュールを適応させようとした後、最終的に自分自身の Sub::Chain を抽象化しました。いくつかの作業が必要ですが、これまでのところ必要なことを行っています。

長いバージョン: (POD からの抜粋)

=head1 理論的根拠

このモジュールは、Data::Transform::Named として開始されました。これは、Data::Transform (具体的には Data::Transform::Map) の名前付きラッパー (Sub::Chain::Named など) です。

モジュールがほぼ完成したので、Data::Transform をほとんど使用していないことに気付きました (そして、そのドキュメントは、II が使用している唯一の部分を使用したくないことを示唆していました)。また、出力が常に期待どおりであるとは限らないこともわかりました。私は、Data::Transform の考えられる目的に照らすと妥当であると判断し、このモジュールは単純に異なる必要があると判断しました。

そこで、もっと抽象的に考えてみたところ、モジュールの本質はデータ変換に結びついているのではなく、単純なサブルーチン呼び出しの連続にすぎないことに気付きました。

次に、Sub::Pipeline を見つけて検討しましたが、1 つのチェーンで同じ名前のサブルーチンを異なる引数で使用できるようにする必要がありました。さらに少し。

探していた時期に開発が始まっていたRule::Engineも調べてみました。しかし、Data::Transform のように、必要以上に複雑に思えました。Rule::Engine が [非常に優れた] Moose を使用しているのを見たとき、古いディストリビューションと古い perl を使用し、リソースが限られた多くの非常に古いマシンで作業を行っていたため、パスすることにしました。繰り返しますが、それは私が探していたものをはるかに超えているように見えました.

=カット

私の元のアイデア/例の「解析」メソッドについては、それが必要であることがわかりませんでした。現在、次のような構文を使用しています

$chain->append($sub, \@arguments, \%options)

于 2011-01-07T19:15:54.417 に答える
0

私はデータ変換 CPAN モジュールを認識していないので、自分で作成する必要がありました。これはこれよりもはるかに複雑でしたが、同様の原則の下で動作しました。それは基本的に、派手な GUI のない Informatica スタイルの ETL の貧弱な実装でした... 構成は Perl ハッシュでした (特定の複雑なルールをサブルーチン参照として実装できるため、XML の代わりに Perl を使用しました)。

名前空間に関しては、私は行きますData::Transform::*

于 2010-11-17T19:43:51.347 に答える