diff options
author | Austin Ziegler <austin@zieglers.ca> | 2019-01-28 00:42:50 -0500 |
---|---|---|
committer | Austin Ziegler <austin@zieglers.ca> | 2019-02-01 22:25:37 -0500 |
commit | a798f6f1dc5d41aceb236ea0aeaa113c8dc89c92 (patch) | |
tree | d9f368b89273969d87f4f5b640d855c7336f453e /lib | |
parent | 45ea1b30c7de0ad840f72afb82fd41eb2b9590db (diff) | |
download | diff-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.rb | 18 | ||||
-rw-r--r-- | lib/diff/lcs/change.rb | 4 | ||||
-rw-r--r-- | lib/diff/lcs/internals.rb | 24 |
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 |