Class: Jinx::Uniquifier

Inherits:
Object show all
Includes:
Singleton
Defined in:
lib/jinx/helpers/uniquifier.rb

Overview

A utility class to generate value qualifiers.

Constant Summary collapse

CHARS =
'abcdefghijkmnpqrstuvwxyz23456789'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeUniquifier



24
25
26
# File 'lib/jinx/helpers/uniquifier.rb', line 24

def initialize
  @cache = Jinx::LazyHash.new { Hash.new }
end

Class Method Details

.qualifierObject

Returns a relatively unique integral qualifier. Successive calls to this method within the same time zone spaced more than a millisecond apart return different integers. Each generated qualifier is greater than the previous by an unspecified amount.



13
14
15
16
17
18
19
20
21
22
# File 'lib/jinx/helpers/uniquifier.rb', line 13

def self.qualifier
  # the first date that this method could be called
  @first ||= Date.new(2011, 12, 01)
  # days as integer + milliseconds as fraction since the first date
  diff = DateTime.now - @first
  # shift a tenth of a milli up into the integer portion
  decimillis = diff * 24 * 60 * 60 * 10000
  # truncate the fraction
  decimillis.truncate
end

Instance Method Details

#clearObject



60
61
62
# File 'lib/jinx/helpers/uniquifier.rb', line 60

def clear
  @cache.clear
end

#to_unique(value) ⇒ String (private)

Returns the new unique value, or nil if the given value is nil.

Raises:

  • (ArgumentError)

    if value is neither a String nor nil



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/jinx/helpers/uniquifier.rb', line 71

def to_unique(value)
  return if value.nil?
  raise ArgumentError.new("#{value.qp} is not a String") unless String === value
  s = ''
  n = Jinx::Uniquifier.qualifier
  while n > 0 do
    n, m = n.divmod(32)
    s << CHARS[m]
  end
  [value.gsub(' ', '_'), s].join('_')
end

#uniquify(obj, value = nil) ⇒ String?

Returns a relatively unique String for the given base String object or (object, String value) pair. In the former case, each call returns a distinct value. In the latter case, successive calls of the same String value for the same object class return the same unique value.

This method is useful to transform a String object key to a unique value for testing purposes.

The unique value is comprised of a prefix and suffix. The prefix is the base value with spaces replaced by an underscore. The suffix is a qualifier converted to digits and lower-case letters, excluding the digits 0, 1 and characters l, o to avoid confusion.

Examples:

Jinx::Uniquifier.instance.uniquify('Groucho') #=> Groucho_wiafye6e
Jinx::Uniquifier.instance.uniquify('Groucho') #=> Groucho_uqafye6e
Jinx::Uniquifier.instance.uniquify('Groucho Marx') #=> Groucho_ay23ye6e
Jinx::Uniquifier.instance.uniquify(person, 'Groucho') #=> Groucho_wy874e6e
Jinx::Uniquifier.instance.uniquify(person, 'Groucho') #=> Groucho_wy87ye6e


52
53
54
55
56
57
58
# File 'lib/jinx/helpers/uniquifier.rb', line 52

def uniquify(obj, value=nil)
  if String === obj then
    to_unique(obj)
  elsif value then
    @cache[obj.class][value] ||= to_unique(value)
  end
end