Module HashDiff
In: lib/hashdiff/diff.rb
lib/hashdiff/util.rb
lib/hashdiff/lcs.rb
lib/hashdiff/version.rb
lib/hashdiff/linear_compare_array.rb
lib/hashdiff/patch.rb

This module provides methods to diff two hash, patch and unpatch hash

Methods

Classes and Modules

Class HashDiff::LinearCompareArray

Constants

VERSION = '0.3.6'

Public Class methods

Best diff two objects, which tries to generate the smallest change set using different similarity values.

HashDiff.best_diff is useful in case of comparing two objects which include similar hashes in arrays.

@param [Array, Hash] obj1 @param [Array, Hash] obj2 @param [Hash] options the options to use when comparing

  * :strict (Boolean) [true] whether numeric values will be compared on type as well as value.  Set to false to allow comparing Integer, Float, BigDecimal to each other
  * :delimiter (String) ['.'] the delimiter used when returning nested key references
  * :numeric_tolerance (Numeric) [0] should be a positive numeric value.  Value by which numeric differences must be greater than.  By default, numeric values are compared exactly; with the :tolerance option, the difference between numeric values must be greater than the given value.
  * :strip (Boolean) [false] whether or not to call #strip on strings before comparing
  * :array_path (Boolean) [false] whether to return the path references for nested values in an array, can be used for patch compatibility with non string keys.

@yield [path, value1, value2] Optional block is used to compare each value, instead of default #==. If the block returns value other than true of false, then other specified comparison options will be used to do the comparison.

@return [Array] an array of changes.

  e.g. [[ '+', 'a.b', '45' ], [ '-', 'a.c', '5' ], [ '~', 'a.x', '45', '63']]

@example

  a = {'x' => [{'a' => 1, 'c' => 3, 'e' => 5}, {'y' => 3}]}
  b = {'x' => [{'a' => 1, 'b' => 2, 'e' => 5}] }
  diff = HashDiff.best_diff(a, b)
  diff.should == [['-', 'x[0].c', 3], ['+', 'x[0].b', 2], ['-', 'x[1].y', 3], ['-', 'x[1]', {}]]

@since 0.0.1

@private

check if objects are comparable

@private

check for equality or "closeness" within given tolerance

@private

count node differences

@private

count total nodes for an object

@private

try custom comparison

@private

decode property path into an array @param [String] path Property-string @param [String] delimiter Property-string delimiter

e.g. "a.b[3].c" => [‘a’, ‘b’, 3, ‘c’]

Compute the diff of two hashes or arrays

@param [Array, Hash] obj1 @param [Array, Hash] obj2 @param [Hash] options the options to use when comparing

  * :strict (Boolean) [true] whether numeric values will be compared on type as well as value.  Set to false to allow comparing Integer, Float, BigDecimal to each other
  * :similarity (Numeric) [0.8] should be between (0, 1]. Meaningful if there are similar hashes in arrays. See {best_diff}.
  * :delimiter (String) ['.'] the delimiter used when returning nested key references
  * :numeric_tolerance (Numeric) [0] should be a positive numeric value.  Value by which numeric differences must be greater than.  By default, numeric values are compared exactly; with the :tolerance option, the difference between numeric values must be greater than the given value.
  * :strip (Boolean) [false] whether or not to call #strip on strings before comparing
  * :array_path (Boolean) [false] whether to return the path references for nested values in an array, can be used for patch compatibility with non string keys.

@yield [path, value1, value2] Optional block is used to compare each value, instead of default #==. If the block returns value other than true of false, then other specified comparison options will be used to do the comparison.

@return [Array] an array of changes.

  e.g. [[ '+', 'a.b', '45' ], [ '-', 'a.c', '5' ], [ '~', 'a.x', '45', '63']]

@example

  a = {"a" => 1, "b" => {"b1" => 1, "b2" =>2}}
  b = {"a" => 1, "b" => {}}

  diff = HashDiff.diff(a, b)
  diff.should == [['-', 'b.b1', 1], ['-', 'b.b2', 2]]

@since 0.0.1

@private

caculate array difference using LCS algorithm en.wikipedia.org/wiki/Longest_common_subsequence_problem

@private

get the node of hash by given path parts

Apply patch to object

@param [Hash, Array] obj the object to be patched, can be an Array or a Hash @param [Array] changes e.g. [[ ’+’, ‘a.b’, ‘45’ ], [ ’-’, ‘a.c’, ‘5’ ], [ ’~’, ‘a.x’, ‘45’, ‘63’]] @param [Hash] options supports following keys:

  * :delimiter (String) ['.'] delimiter string for representing nested keys in changes array

@return the object after patch

@since 0.0.1

@private

judge whether two objects are similar

Unpatch an object

@param [Hash, Array] obj the object to be unpatched, can be an Array or a Hash @param [Array] changes e.g. [[ ’+’, ‘a.b’, ‘45’ ], [ ’-’, ‘a.c’, ‘5’ ], [ ’~’, ‘a.x’, ‘45’, ‘63’]] @param [Hash] options supports following keys:

  * :delimiter (String) ['.'] delimiter string for representing nested keys in changes array

@return the object after unpatch

@since 0.0.1

[Validate]