NAME
Algorithm::Diff::Apply -- apply one or more Algorithm::Diff diffs
SYNOPSIS
## Single-diff form:
use Algorithm::Diff::Apply qw{apply_diff};
my @ary = ...;
my @diff = ...; # some call to Algorithm::Diff::diff()
my @changed_ary = apply_diff(\@ary, \@diff);
my $changed_ary = apply_diff(\@ary, \@diff);
## To apply >1 diff at once, use the plural form:
use Algorithm::Applydiffs qw{apply_diffs};
@newary = apply_diffs(\@ary,
diff1_name => \@diff1,
diff2_name => \@diff2,
...
diffN_name => \@diffN);
# Alternatively:
@newary = apply_diffs(\@ary, %named_diffs);
# Scalar context:
$newary = apply_diffs(\@ary, %named_diffs);
# Extension argument syntax:
$newary = apply_diffs(\@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.
- apply_diff ARRAY,DIFFSEQ
-
Applies the changes described by a diff sequence to a copy of an array. DIFFSEQ must be a diff generated by
Algorithm::Diff::diff()
, and ARRAY must be an array of an appropriate length. Both parameters must be passed in as references.In scalar context,
apply_diff
returns a reference to the permuted copy that's generated. In an array context, the permuted copy is returned as an array value.This version of the algorithm is a little simpler and quicker than the full-blown plural form, and should be used if you're only ever going to be applying one diff at once.
- apply_diffs ARRAY,HASH
- apply_diffs ARRAY,OPTIONS,HASH
-
Applies more than one diff sequence to a copy of an array at once, manages conflicts, and returns the permuted copy as either a reference or an array depending on context. The HASH parameter contains diffs generated by
Algorithm::Diff::diff()
, keyed by arbitrary strings. ARRAY must be a reference to an array value. The array behind the passed refrence is not permuted.The diffs sequences are passed in as a hash in order to provide a meaningful and unique label for each diff. This convention is also used by
resolver
callbacks (see below), and can make conflict output more understandable to humans if you don't provide aresolver
. A label for a diff sequences can be any string you like, provided it's unique;Algorithm::Diff::Apply
doesn't care about the exact syntax.OPTIONS, if specified, must be a hash reference of option keywords and the corresponding parameters. The following options are recognised:
- "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 mainapply_diffs()
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 will be spliced into the array that
apply_diffs()
is going to return.There are a scad of other options too, but these are undocumented because they're liable to change.
- mark_conflicts HASH
-
This is the builtin
resolver
callback, used byapply_diffs()
by default. See above for details of its interface. It causesapply_diffs()
to return arrays looking a bit like:[ @part_before_conflict, ">>>>>> diff1_name\n", @lines_1, # Lines permuted by diff1 (only) ">>>>>> diff2_name\n" @lines_2, # The same lines, permuted by diff2 "<<<<<<\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::Diff::Apply
does not yet optimise identical or similar change hunks from different diffs, although that is planned for the future.
The calling convention for options is ugly and confusing, and defeats prototyping. It's done like that to correspond with other modules in the Algorithm::{Diff,Patch} family.
AUTHOR
Andrew Chadwick, andrewc-algodiffaply@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.