NAME
Algorithm::ApplyDiffs -- apply one or more Algorithm::Diff diffs
SYNOPSIS
# Setup
use Algorithm::Applydiffs qw{applydiffs};
my @diff1 = generate_diff_somehow();
my @diff2 = generate_diff_somehow();
...
my @diffN = generate_diff_somehow();
my @ary = generate_array_somwhow();
# Usage:
@newary = applydiffs(\@ary,
diff1_name => \@diff1,
diff2_name => \@diff2,
...
diffN_name => \@diffN);
# or:
@newary = applydiffs(\@ary, %named_diffs);
# Scalar context:
$newary = applydiffs(\@ary, %named_diffs);
# Extension arguments:
$newary = applydiffs(\@ary, {
resolver => \&some_sub,
opt1 => ...,
opt2 => ...,
}, %named_diffs);
DESCRIPTION
This module contains subroutines for applying diff sequences generated by Algorithm::Diff to a target array in the hope of regenerating a new array incorporating all the changes described by the diff sequences.
If two hunks from different diff sequences happen to affect the same line, conflicts are detected and handed off to a helper subroutine for resolution.
applydiffs()
@array_new = applydiffs(\@array_old, %named_diffs);
$arrayref_new = applydiffs(\@array_old, %named_diffs);
Returns an operated-on copy of @array_old with all the diff sequences in %named_diffs applied to it. In a scalar context, applydiffs() returns the new array as a reference instead of as an array.
@array_new = applydiffs(\@array_old, \%opts, %named_diffs);
$arrayref_new = applydiffs(\@array_old, \%opts, %named_diffs);
A hash-reference containing extension options can be passed in as a second argument. Currently recognised options to applydiffs() are:
- resolver
-
This option can be used to supply a subroutine which will be called when a conflict is detected. The job of this callback is to return some kind of resolution of the conflicting sub-arrays. The sub is called a little like this:
@ret = $callback->(alt_txts => { diff1_name => ['m', 'n', 'o'], diff3_name => [], } );
The
alt_txts
parameter is a hash ref keyed by (some of the) names of the diffs being applied in the main applydiffs() call, whose values are arrays containing alternative generated subsequences. Each of these subsequences is the result of applying a set of hunks from the corresponding diff to a copy of the slice of the source array where the conflict happened.A resolver callback is expected to return an array which is spliced into the array that applydiffs() is going to return.
There are a scad of other options too, but these are undocumented because they're liable to change.
mark_conflicts()
mark_conflicts(alt_txts => {
$diff1_name => \@alt1,
$diff2_name => \@alt2,
...,
});
This is the builtin resolver
callback, used by applydiffs() by default. It causes applydiffs() to return arrays looking a bit like:
[ @part_before_conflict,
">>>>>> diff1_name\n",
@lines_from_diff1_only,
">>>>>> diff2_name\n"
@lines_from_diff2_only,
"<<<<<<\n",
@part_after_conflict,
]
Which is probably the right thing to do if your array is going to be printed out one item per line.
BUGS AND TODO
This thing was going to be called Algorithm::Patch, but that's far too grandiose a description for the simplistic activity performed by this module. For one thing, Algorithm::Diff doesn't (yet) generate contexts, so fuzzing would be out of the question.
Algorithm::ApplyDiffs does not yet optimise identical or similar change hunks from different diffs, although that is planned for the future.
AUTHOR
Andrew Chadwick, andrewc-algoaplydiff@piffle.org.
LICENCE
Copyright (c) 2003 Andrew Chadwick. This program is free software; you may copy it, redistribute it, or modify it under the same terms as Perl itself.