Location : Home > Languages > Perl > Package Title : Algorithm::Merge |
![]() |
Algorithm::Merge - マージ3種
use Algorithm::Merge qw(merge diff3 traverse_sequences3); @merged = merge(\@ancestor, \@a, \@b, { CONFLICT => sub { } }); @merged = merge(\@ancestor, \@a, \@b, { CONFLICT => sub { } }, $key_generation_function); $merged = merge(\@ancestor, \@a, \@b, { CONFLICT => sub { } }); $merged = merge(\@ancestor, \@a, \@b, { CONFLICT => sub { } }, $key_generation_function); @diff = diff3(\@ancestor, \@a, \@b); @diff = diff3(\@ancestor, \@a, \@b, $key_generation_function); $diff = diff3(\@ancestor, \@a, \@b); $diff = diff3(\@ancestor, \@a, \@b, $key_generation_function); @trav = traverse_sequences3(\@ancestor, \@a, \@b, { # callbacks }); @trav = traverse_sequences3(\@ancestor, \@a, \@b, { # callbacks }, $key_generation_function); $trav = traverse_sequences3(\@ancestor, \@a, \@b, { # callbacks }); $trav = traverse_sequences3(\@ancestor, \@a, \@b, { # callbacks }, $key_generation_function);
本モジュールは3種の merge 及び diff 関数を提供することで Algorithm::Diff を補完する。
本ドキュメントでは1つめは「オリジナルリスト」と呼ばれる diff3, merge, traverse_sequences3 である。2つめは 'left' リストである。3つめは 'right' リストである。
オプションのキー生成引数は Algorithm::Diff と同じである。詳しくは Algorithm::Diff を参照のこと。
diff3
3つのリストへの参照が与えられたとき、diff3 は3種の差異を計算する。
この関数はオリジナルのリストから左右のリストがどれくらい異なっているかを記述する演算の配列を返す。
スカラコンテキストではこの関数は配列への参照を返す。
おそらく例が有用だろう。
以下のような3つのリストが与えられたとする。
original: a b c e f h i k left: a b d e f g i j k right: a b c d e h i j k merge: a b d e g i j k
diff3 から以下の結果を得る。
[ 'u', 'a', 'a', 'a' ], [ 'u', 'b', 'b', 'b' ], [ 'l', 'c', undef, 'c' ], [ 'o', undef, 'd', 'd' ], [ 'u', 'e', 'e', 'e' ], [ 'r', 'f', 'f', undef ], [ 'o', 'h', 'g', 'h' ], [ 'u', 'i', 'i', 'i' ], [ 'o', undef, 'j', 'j' ], [ 'u', 'k', 'k', 'k' ]
各行の最初の要素は差異についての配列である。
c - 衝突(conflict;2つは同一)
l - 左が違う(left is different)
o - 元が違う(original is different)
r - 右が違う(right is different)
u - 変化なし(unchanged)
次の3つの要素は行が参照するオリジナル・左右の配列からのリストである。(概要ではそれぞれ @ancestor, @a, @b であった。)
merge
項目の3つのリストが与えられた時、merge は3種のマージを実行する。merge 関数はその作業のほとんどで diff3 関数を利用する。
現在利用しているコールバックは2つの配列参照を受け付けるサブルーチンへの参照となるべき CONFLICT である。
最初の配列参照は左リストからの要素のリストへのものである。
最初の配列参照は右リストからの要素のリストへのものである。
このコールバックは衝突が起こっている照合されたリストの場所の要素のリストを返す。
デフォルトの CONFLICT コールバックは以下のようなものを返す。
q{<!-- ------ START CONFLICT ------ -->}, (@left), q{<!-- ---------------------------- -->}, (@right), q{<!-- ------ END CONFLICT ------ -->},
traverse_sequences3
これは3つのシーケンスを渡し、コールバック関数を呼び出す。
以下のコールバックがサポートされている。
NO_CHANGE
3つのシーケンスが現在の場所で同じ要素を保持しているときに呼び出される。引数はそれぞれのシーケンスにおける現在の位置で、最初の引数は最初シーケンスの現在の位置である。
A_DIFF
これは1つめのシーケンスが現在の位置で他の2つのシーケンスに対し異なる要素を保持している場合に呼び出される。このコールバックは1または2、3この引数をとる。
引数が1つであれば、1つめのシーケンスの所与の位置における要素が他のいずれのシーケンスに見当たらない場合である。
引数が2つであれば、2つめと3つめのシーケンスの所与の位置における要素に対応する要素が1つめのシーケンスにない場合である。
引数が3つであれば、1つめのシーケンスの所与の位置における要素が他のシーケンスの対応する要素と異なるが他の2つのシーケンスでは一致している場合である。
B_DIFF
これは2つめのシーケンスが現在の位置で他の2つのシーケンスに対し異なる要素を保持している場合に呼び出される。このコールバックは1または2、3この引数をとる。
引数が1つであれば、2つめのシーケンスの所与の位置における要素が他のいずれのシーケンスに見当たらない場合である。
引数が2つであれば、1つめと3つめのシーケンスの所与の位置における要素に対応する要素が2つめのシーケンスにない場合である。
引数が3つであれば、2つめのシーケンスの所与の位置における要素が他のシーケンスの対応する要素と異なるが他の2つのシーケンスでは一致している場合である。
C_DIFF
これは3つめのシーケンスが現在の位置で他の2つのシーケンスに対し異なる要素を保持している場合に呼び出される。このコールバックは1または2、3この引数をとる。
引数が1つであれば、3つめのシーケンスの所与の位置における要素が他のいずれのシーケンスに見当たらない場合である。
引数が2つであれば、1つめと2つめのシーケンスの所与の位置における要素に対応する要素が2つめのシーケンスにない場合である。
引数が3つであれば、3つめのシーケンスの所与の位置における要素が他のシーケンスの対応する要素と異なるが他の2つのシーケンスでは一致している場合である。
CONFLICT
これは3つの全てのシーケンスは現在の位置で全く異なる要素を保持している場合に呼び出される。3つの引数はそれぞれのシーケンスにおける現在の位置である。
たぶんバグはあるだろう。上記サンプルに近いパターンでうまく動かなかった場合は、<jsmith@cpan.org> にメールを送るかまたは CPAN のバグ・トラッカー http://rt.cpan.org/ に報告して欲しい。
traverse_sequences の Algorithm::Diff の実装は、2番目と3番目のシーケンスが異なる長さを持つ場合に入力を尊重して対称でないかも知れない。このために traverse_sequences3 は2番目と3番目のシーケンスに対して diff を計算しても通して入れ替える。もし差が同じでなければ 'Algorithm::Diff::diff is not symmetric for second and third sequences...' という警告がでる。これを処理しようとしているのだが今のところうまくいっていない。
James G. Smith, <jsmith@cpan.org>
Copyright (C) 2003 Texas A&M University. All Rights Reserved.
本モジュールはフリーソフトウェアであり、Perl 本体と同等の条件で修正/再配布してもよい。
![]() |
Updated : 2007/06/11 |