=pod

=head1 NAME

Algorithm::Diff::Apply -- apply one or more Algorithm::Diff diffs

=head1 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);

=head1 DESCRIPTION

This module contains subroutines for applying diff sequences generated
by C<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.

=over 4

=item apply_diff ARRAY,DIFFSEQ

Applies the changes described by a diff sequence to a copy of an array.
I<DIFFSEQ> must be a diff generated by C<Algorithm::Diff::diff()>, and
I<ARRAY> must be an array of an appropriate length. Both parameters must be
passed in as references.

In scalar context, C<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.

=item apply_diffs ARRAY,HASH

=item 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 I<HASH> parameter contains diffs generated by
C<Algorithm::Diff::diff()>, keyed by arbitrary strings. I<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
C<resolver> callbacks (see below), and can make conflict output more
understandable to humans if you don't provide a C<resolver>. A label for a
diff sequences can be any string you like, provided it's unique;
C<Algorithm::Diff::Apply> doesn't care about the exact syntax.

I<OPTIONS>, if specified, must be a hash reference of option keywords and
the corresponding parameters. The following options are recognised:

=over 4

=item "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 C<alt_txts> parameter is a hash ref keyed by (some of the) names of the
diffs being applied in the main C<apply_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 C<apply_diffs()> is going to return.

There are a scad of other options too, but these are undocumented because
they're liable to change.

=back

=item mark_conflicts HASH

This is the builtin C<resolver> callback, used by C<apply_diffs()> by
default. See above for details of its interface.  It causes
C<apply_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.

=back

=head1 BUGS AND TODO

This thing was going to be called I<Algorithm::Patch>, but that's far too
grandiose a description for the simplistic activity performed by this
module. For one thing, C<Algorithm::Diff> doesn't (yet) generate contexts,
so fuzzing would be out of the question.

C<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
I<Algorithm::{Diff,Patch}> family.

=head1 AUTHOR

Andrew Chadwick, I<andrewc-algodiffaply@piffle.org>.

=head1 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.

=cut

