Sha256: f855ea85215c10875553d1fab413256396bc39f874fd4eabe8e2cb2b923edad1

Contents?: true

Size: 1.47 KB

Versions: 1

Compression:

Stored size: 1.47 KB

Contents

require 'crimp/version'
require 'digest'

class Numeric
  # see http://patshaughnessy.net/2014/1/9/how-big-is-a-bignum
  def bignum?
    self >= 4611686018427387904
  end
end

module Crimp
  def self.signature(obj)
    Digest::MD5.hexdigest stringify(obj)
  end

  def self.stringify(obj)
    convert(obj).tap { |o| return o.class == String ? o : to_string(o) }
  end

  private

  def self.convert(obj)
    case obj
    when Array
      parse_array obj
    when Hash
      parse_hash obj
    when String
      obj
    else
      to_string obj
    end
  end

  def self.hash_to_array(hash)
    [].tap do |a|
      hash.each { |k, v| a << pair_to_string(k, v) }
    end
  end

  def self.pair_to_string(k, v)
    "#{stringify k}=>#{stringify v}"
  end

  def self.parse_array(array)
    array.map { |e| stringify(e) }.sort
  end

  def self.parse_hash(hash)
    stringify hash_to_array(hash)
  end

  def self.to_string(obj)
    "#{obj}#{legacy_class(obj)}"
  end

  # This is for legacy/compatibilty reason:
  #
  # Ruby 2.1
  # 2.class => Fixnum
  # Ruby >= 2.4
  # 2.class => Integer
  #
  # Say you have a huge number of stored keys and you migrate your app from 2.1 to >= 2.4
  # this would cause a change of the signature for a subset of the keys which would be hard
  # to debug especially for nested data structures.
  #
  def self.legacy_class(obj)
    return obj.class unless obj.is_a?(Numeric)
    return 'Float'   if obj.is_a?(Float)
    return 'Bignum'  if obj.bignum?
    'Fixnum'
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
crimp-0.2.0 lib/crimp.rb