Class: Lookout::Diff::Algorithms::Difflib

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/lookout-3.0/diff/algorithms/difflib.rb

Overview

The difflib algorithm is based on the algorithm employed by the difflib library for Python, which is, in turn, based on an algorithm by Ratcliff and Obershelp, see http://docs.python.org/library/difflib.html.

It’s implemented as an Enumerable over the Matches between two sequences. There are very few requirements on these sequences (see #initialize), which makes this implementation useful for a wide class of objects.

Defined Under Namespace

Classes: Position

Instance Method Summary collapse

Instance Method Details

# {|match| ... } ⇒ Object #Enumerator<Match>

Overloads:

  • # {|match| ... } ⇒ Object

    Enumerates the matches between the two sequences. There’ll always be at least one match yielded, the empty one at the end of the sequences.

    Yield Parameters:

  • #Enumerator<Match>

    Returns An Enumerator over the matches between the two sequences.

    Returns:

    • (Enumerator<Match>)

      An Enumerator over the matches between the two sequences

Yields:

  • (current)


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/lookout-3.0/diff/algorithms/difflib.rb', line 36

def each
  return enum_for(__method__) unless block_given?
  current = Lookout::Diff::Match.new(Lookout::Diff::Slice.new(old, 0...0),
                                     Lookout::Diff::Slice.new(new, 0...0))
  stack = [Position.origin(old, new, &ignorable)]
  until stack.empty?
    case item = stack.pop
    when Position
      match = item.match
      next if match.empty?
      stack.push item.begin_after(match) if item.end_after? match
      stack.push match
      stack.push item.end_before(match) if item.begin_before? match
    when Lookout::Diff::Match
      if current.touch? item
        current += item
      else
        yield current unless current.empty?
        current = item
      end
    end
  end
  yield current unless current.empty?
  yield current.at(old.size...old.size, new.size...new.size)
  self
end