summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAustin Ziegler <austin@zieglers.ca>2019-01-28 00:42:50 -0500
committerAustin Ziegler <austin@zieglers.ca>2019-02-01 22:25:37 -0500
commita798f6f1dc5d41aceb236ea0aeaa113c8dc89c92 (patch)
treed9f368b89273969d87f4f5b640d855c7336f453e /lib
parent45ea1b30c7de0ad840f72afb82fd41eb2b9590db (diff)
downloaddiff-lcs-a798f6f1dc5d41aceb236ea0aeaa113c8dc89c92.tar.gz
Reintroduce Diff::LCS::Change#to_ary
- This required some level of code remediation in the main library, but all tests now pass: - Patchsets are now internally flattened one level explicitly, rather than using Array#flatten. This ensures that only the outer patchset array is flattened. Fixes #48.
Diffstat (limited to 'lib')
-rw-r--r--lib/diff/lcs.rb18
-rw-r--r--lib/diff/lcs/change.rb4
-rw-r--r--lib/diff/lcs/internals.rb24
3 files changed, 32 insertions, 14 deletions
diff --git a/lib/diff/lcs.rb b/lib/diff/lcs.rb
index d3a75fd..f33a452 100644
--- a/lib/diff/lcs.rb
+++ b/lib/diff/lcs.rb
@@ -50,7 +50,7 @@ module Diff; end unless defined? Diff # rubocop:disable Style/Documentation
# a x b y c z p d q
# a b c a x b y c z
module Diff::LCS
- VERSION = '1.3'
+ VERSION = '1.4'
end
require 'diff/lcs/callbacks'
@@ -181,6 +181,20 @@ class << Diff::LCS
# Class argument is provided for +callbacks+, #diff will attempt to
# initialise it. If the +callbacks+ object (possibly initialised) responds
# to #finish, it will be called.
+ #
+ # Each element of a returned array is a Diff::LCS::ContextChange object,
+ # which can be implicitly converted to an array.
+ #
+ # Diff::LCS.sdiff(a, b).each do |action, (old_pos, old_element), (new_pos, new_element)|
+ # case action
+ # when '!'
+ # # replace
+ # when '-'
+ # # delete
+ # when '+'
+ # # insert
+ # end
+ # end
def sdiff(seq1, seq2, callbacks = nil, &block) #:yields diff changes:
diff_traversal(:sdiff, seq1, seq2, callbacks || Diff::LCS::SDiffCallbacks, &block)
end
@@ -623,7 +637,7 @@ class << Diff::LCS
patch_map = PATCH_MAP[direction]
- patchset.flatten.each do |change|
+ patchset.each do |change|
# Both Change and ContextChange support #action
action = patch_map[change.action]
diff --git a/lib/diff/lcs/change.rb b/lib/diff/lcs/change.rb
index 75e1f84..76faf83 100644
--- a/lib/diff/lcs/change.rb
+++ b/lib/diff/lcs/change.rb
@@ -39,6 +39,8 @@ class Diff::LCS::Change
[@action, @position, @element]
end
+ alias to_ary to_a
+
def self.from_a(arr)
arr = arr.flatten(1)
case arr.size
@@ -125,6 +127,8 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
]
end
+ alias to_ary to_a
+
def self.from_a(arr)
Diff::LCS::Change.from_a(arr)
end
diff --git a/lib/diff/lcs/internals.rb b/lib/diff/lcs/internals.rb
index c3360d5..60027f2 100644
--- a/lib/diff/lcs/internals.rb
+++ b/lib/diff/lcs/internals.rb
@@ -91,14 +91,15 @@ class << Diff::LCS::Internals
vector
end
- # This method will analyze the provided patchset to provide a
- # single-pass normalization (conversion of the array form of
- # Diff::LCS::Change objects to the object form of same) and detection of
- # whether the patchset represents changes to be made.
+ # This method will analyze the provided patchset to provide a single-pass
+ # normalization (conversion of the array form of Diff::LCS::Change objects to
+ # the object form of same) and detection of whether the patchset represents
+ # changes to be made.
def analyze_patchset(patchset, depth = 0)
fail 'Patchset too complex' if depth > 1
has_changes = false
+ new_patchset = []
# Format:
# [ # patchset
@@ -108,29 +109,28 @@ class << Diff::LCS::Internals
# ]
# ]
- patchset = patchset.map { |hunk|
+ patchset.each do |hunk|
case hunk
when Diff::LCS::Change
has_changes ||= !hunk.unchanged?
- hunk
+ new_patchset << hunk
when Array
- # Detect if the 'hunk' is actually an array-format
- # Change object.
+ # Detect if the 'hunk' is actually an array-format change object.
if Diff::LCS::Change.valid_action? hunk[0]
hunk = Diff::LCS::Change.from_a(hunk)
has_changes ||= !hunk.unchanged?
- hunk
+ new_patchset << hunk
else
with_changes, hunk = analyze_patchset(hunk, depth + 1)
has_changes ||= with_changes
- hunk.flatten
+ new_patchset.concat(hunk)
end
else
fail ArgumentError, "Cannot normalise a hunk of class #{hunk.class}."
end
- }
+ end
- [has_changes, patchset.flatten(1)]
+ [has_changes, new_patchset]
end
# Examine the patchset and the source to see in which direction the