global
def patch(src, patchset, direction = nil)
representations of those objects. Prior to application, array
containing either Diff::LCS::Change objects (or a subclass) or the array
The +patch+ method accepts patchsets that are enumerable sequences
]
]
# change
[ # hunk
# change
[ # patchset
changes:
or a mix of the two. A hunk of changes is an enumerable sequence of
A +patchset+ is always an enumerable sequence of changes, hunks of changes,
=== Patchsets
patchset.flatten(1).all? { |change| change.unchanged? }
patchset.empty? or
changes if the following predicate returns true:
either src.dup or +src+. A +patchset+ can be deemed as having no
If the +patchset+ contains no changes, the +src+ value will be returned as
patch(s2, diff(s1, s2)) -> s1
following expression is true:
A +patchset+ can be considered to apply backward (:unpatch) if the
patch(s1, diff(s1, s2)) -> s2
following expression is true:
A +patchset+ can be considered to apply forward (:patch) if the
discover the direction of the +patchset+.
If the +direction+ is not specified, Diff::LCS::patch will attempt to
(:patch or :unpatch), producing a new sequence.
Applies a +patchset+ to the sequence +src+ according to the +direction+
def patch(src, patchset, direction = nil) # Normalize the patchset. has_changes, patchset = Diff::LCS::Internals.analyze_patchset(patchset) return src.respond_to?(:dup) ? src.dup : src unless has_changes string = src.kind_of?(String) # Start with a new empty type of the source's class res = src.class.new direction ||= Diff::LCS::Internals.intuit_diff_direction(src, patchset) ai = bj = 0 patch_map = PATCH_MAP[direction] patchset.each do |change| # Both Change and ContextChange support #action action = patch_map[change.action] case change when Diff::LCS::ContextChange case direction when :patch el = change.new_element op = change.old_position np = change.new_position when :unpatch el = change.old_element op = change.new_position np = change.old_position end case action when '-' # Remove details from the old string while ai < op res << (string ? src[ai, 1] : src[ai]) ai += 1 bj += 1 end ai += 1 when '+' while bj < np res << (string ? src[ai, 1] : src[ai]) ai += 1 bj += 1 end res << el bj += 1 when '=' # This only appears in sdiff output with the SDiff callback. # Therefore, we only need to worry about dealing with a single # element. res << el ai += 1 bj += 1 when '!' while ai < op res << (string ? src[ai, 1] : src[ai]) ai += 1 bj += 1 end bj += 1 ai += 1 res << el end when Diff::LCS::Change case action when '-' while ai < change.position res << (string ? src[ai, 1] : src[ai]) ai += 1 bj += 1 end ai += 1 when '+' while bj < change.position res << (string ? src[ai, 1] : src[ai]) ai += 1 bj += 1 end bj += 1 res << change.element end end end while ai < src.size res << (string ? src[ai, 1] : src[ai]) ai += 1 bj += 1 end res end