Practice of Programming

プログラム とか Linuxとかの話題

固定的なデータに対してフィルタをかけるためのモジュール

固定的な(テンプレートのような)データに対して、必要な箇所にピンポイントで変更を行うためのものです。
データに対するフィルタリング処理は再帰的にデータを調べて、変更していくのが普通だと思いますが、データが大きくなると、コストが高くなってしまいます。
Glueでルールを解析した後のデータ化したものにフィルタする必要があって作ったものです。


Data::Patch(という名前を付けてますが適切じゃない気がする)
ドキュメント
http://rwds.net/tmp/patch.html
コード
http://rwds.net/trac.cgi/file/modules/Data-Patch/lib/Data/Patch.pm


このモジュールは、parse時に、「変換したいデータへの行き方と、そこでやる関数」をまとめたもの返して、それを、データに対して適用(patch)してやることで、データのフィルタリングを実現します。
parseは遅いかもしれないけど、parseの結果を保存しといてやれば、patchは断然速いです。


「変換したいデータへの行き方と、そこでやる関数」てのは、ドキュメントにありますが、下記のようなもの。

  # $data の 'localtime' を sub{scalar(localtime)}に変えたい
  $data = [
             {
               c => 
                 {
                   b => ['localtime']
                 }
              }
          ]

  $patch =
        [
          [
            sub {(\${$_[0]}{'c'}, $_[0]->{'c'})},
            sub {(\${$_[0]}{'b'}, $_[0]->{'b'})},
            sub {(\${$_[0]}[0]  , $_[0]->[0])},
            sub {sub{scalar(localtime)}},
          ]
        ]

$patchの配列リファレンスをたどっていけば、目的の 'localtime' に行き着くということです。簡略化してますが、元のデータは関数内で扱えますし、他で作ったオブジェクトとかを、patchに渡して関数内で使うことも出来ます。


ちなみに、ある程度できたときに、Dataのテンプレートみたいなだなぁと思って、Data::Templateっていう名前を思い付いて、検索したら、そのまんまのがありました...orzとか思ったけど、これは、TTで変換というものだったので、Data::Patchの存在意義はあるかな、と。ちなみに、Data::Patchのほうが速いです(勿論、parseした後のものをキャッシュしなかったらダメだけど)。


あんまり使い道はないかもしんないけど。