my $a = new MyClass(@data);
print $_, "\n" while <$a>; # @dataがソートされて出力される
のようなコードが動くようなクラスを設計してくれという内容。クラスが作れて、演算子overloadができなければできない課題なのですが、オブジェクト指向でPerlのコードが書けて、なおかつ演算子overloadができるようになってほしいという意図でこの課題を出しました。正確には、自分でイテレータが作れるように成って欲しいという意図もあるわけですが。
実際、クラスが作れて、演算子オーバーロードが使えれば、以前作ったコードが再利用しやすくなるわけで。その再利用するコードも、ある程度汎用性を持たせてかかないといけませんが。例えば、
foreach ($node->getChilds())
{
if ($other_node == $_) ...
}
なんてコードが在れば、$nodeに入るインスタンスのもととなるクラスは、getChildsメソッドを実装していればこのコードは通りますし、さらに'=='をoverloadすれば、クラス独自の比較方法が適用できます。同じリファレンスなのかという比較方法ではなく、同じメンバ変数を持っているのか、という比較を行いたいとき、'=='をoverloadする必要が出てきます。
以前研究のために、1000行ほどのPerlのコードを書きました。研究の流れ上、当分使わないだろうなと思っていたコードなのですが、研究室のバイトで使えそうな雰囲気に。このコードは日本語の係り受け解析の結果得られる構文木を二つ作って置き、これらの木の共通部分木を取り出し、その木のノード数をみて、構文的類似度を求める手法(Tree KernelやらTree Overlappingやら)のコードです。ちなみに、先これを作った後、Tree KernelやTree Overlappingという手法を知り、なんだすでに提案されてるぢゃん!とか衝撃を食らった覚えがありますが、とかく実行できるコードが出来上がったので、後々使えるだろうと置いて置いたのです。
そしてこのコード、何だかクラス依存度を減らして割とジェネリックなコードに書き直せるんじゃなかろうかと思い、以前にクラス間依存度を減らすよう書き直して置いたのです。つまり、構文木の比較のアルゴリズムを記述したコードなのですが、その構文木の内部構造にはタッチしないようなコードに変更したのです。C#などで言えば、構文木クラスをinterfaceとして定義しておき、構文木の比較アルゴリズムではこのinterface classを使って処理を行うようコードを書く、という感覚ですね。
ちなみにこのバイトで作るプログラムは、HTMLドキュメントの構文的類似度を測るというものです。各ノードが、以前は形態素だったり文節だったりしたのですが、今度はHTML要素がノードとなります。このHTML要素クラスを作る際に、係り受け解析によりえられた構文木のノードクラスと同様のインターフェース(もちろん、構文木の比較アルゴリズムに必要なインターフェースのみですが)を持つように設計してやれば、構文的類似度を求めるコードが流用できるようになります。
既存のロジックに見合うよう、クラスを設計してやれば(コーディングの量は大したことありません)、バチっとロジックにはまって一つのプログラムが完成する。ある種の快感のようなものを感じます。この「バチっと」、が4年生に共感してもらえればなぁ、と思っています。
No comments:
Post a Comment