Merge(3pm)
β¨ Merge(3pm) β User Contributed Perl Documentation β¨
Okay bestie, this is the Merge(3pm) page π It's all about the Algorithm::Merge Perl module, and it is genuinely iconic for three-way merging and diffing. Let's get into it π«Ά
πΈ NAME
Algorithm::Merge β Three-way merge and diff π¦
π SYNOPSIS
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);
π USAGE
Okay so this module is basically the bestie of Algorithm::Diff π§ It adds three-way merge and diff functions, and it's giving full main character energy.
In this documentation, the first list passed to diff3, merge, and traverse_sequences3 is called the original list. The second list is the left list. The third list is the right list. Simple, right? π
The optional key generation arguments work exactly the same as they do in Algorithm::Diff. Go check out Algorithm::Diff for more info β¨
π¦ diff3
Given references to three lists of items, diff3 performs a three-way difference. Literally the core of the whole thing π₯
This function returns an array of operations describing how the left and right lists differ from the original list. In scalar context, it returns a reference to that array instead.
Perhaps an example would be useful, bestie π
Given the following three lists,
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
we get the following result from 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' ]
The first element in each row is the tag that describes the difference:
cβ conflict (no two are the same) πlβ left is different πoβ original is different πrβ right is different π§uβ unchanged π«Ά
The next three elements are the items from the original, left, and right arrays respectively that the row refers to (in the synopsis, these are @ancestor, @a, and @b, respectively).
π merge
Given references to three lists of items, merge performs a three-way merge. It leans on diff3 to do most of the heavy lifting π
The only callback currently used is CONFLICT. It should be a reference to a subroutine that accepts two array references. The first array reference points to a list of elements from the left list, and the second points to a list of elements from the right list. Whatever this callback returns gets placed into the merged list in place of the conflict β¨
The default CONFLICT callback returns the following:
q{<!-- ------ START CONFLICT ------ -->},
(@left),
q{<!-- ---------------------------- -->},
(@right),
q{<!-- ------ END CONFLICT ------ -->},
π traverse_sequences3
This is the workhorse function! It goes through the three sequences and calls the callback functions π₯
The following callbacks are supported, bestie:
NO_CHANGE : This gets called if all three sequences have the same element at the current position. The arguments are the current positions within each sequence, with the first argument being the current position within the first sequence.
A_DIFF : This gets called if the first sequence is different from the other two at the current position. It can be called with one, two, or three arguments.
If there's one argument, then only the element at the given position from the first sequence is not in either of the other two sequences.
If there are two arguments, then there is no element in the first sequence that corresponds to the elements at the given positions in the second and third sequences.
If there are three arguments, then the element at the given position in the first sequence is different from the corresponding element in the other two sequences, but those other two sequences have corresponding elements.
B_DIFF : This gets called if the second sequence is different from the other two at the current position. It can be called with one, two, or three arguments.
If there's one argument, then only the element at the given position from the second sequence is not in either of the other two sequences.
If there are two arguments, then there is no element in the second sequence that corresponds to the elements at the given positions in the first and third sequences.
If there are three arguments, then the element at the given position in the second sequence is different from the corresponding element in the other two sequences, but those other two sequences have corresponding elements.
C_DIFF : This gets called if the third sequence is different from the other two at the current position. It can be called with one, two, or three arguments.
If there's one argument, then only the element at the given position from the third sequence is not in either of the other two sequences.
If there are two arguments, then there is no element in the third sequence that corresponds to the elements at the given positions in the first and second sequences.
If there are three arguments, then the element at the given position in the third sequence is different from the corresponding element in the other two sequences, but those other two sequences have corresponding elements.
CONFLICT : This gets called if all three sequences have different elements at the current position. The three arguments are the current positions within each sequence.
π BUGS
Most assuredly there are bugs π If a pattern similar to the example above doesn't work, send it to <jsmith@cpan.org> or report it on <http://rt.cpan.org/>, the CPAN bug tracker.
Heads up:Algorithm::Diff's implementation oftraverse_sequencesmay not be symmetric with respect to the input sequences if the second and third sequences are of different lengths. Because of this,traverse_sequences3will calculate the diffs of the second and third sequences as passed and swapped. If the differences are not the same, it will issue anAlgorithm::Diff::diff is not symmetric for second and third sequences...warning. It will try to handle this, but there may be some cases where it can't.
π¦ SEE ALSO
Algorithm::Diff.
π AUTHOR
James G. Smith, <jsmith@cpan.org>
π«Ά COPYRIGHT
Copyright (C) 2003, 2007 Texas A&M University. All Rights Reserved.
This module is free software; you may redistribute it and/or modify it under the same terms as Perl itself.
Okay that's the whole tea, bestie π Merge(3pm) from perl v5.36.0, dated 2022-10-14, and you are officially a Unix legend now πβ¨
π¦ where this page comes from
- ubuntu noble: libalgorithm-merge-perl 0.08-5 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu questing: libalgorithm-merge-perl 0.08-5 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libalgorithm-merge-perl 0.08-5 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libalgorithm-merge-perl 0.08-5 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by anthropic/claude-haiku-5.5 on : a language model's rewrite of the original, under its terms