Class: Trusty::Sorting::AtomSorter

Inherits:
Object
  • Object
show all
Defined in:
lib/trusty/sorting/atom_sorter.rb

Constant Summary collapse

LEFT_FIRST =
-1
RIGHT_FIRST =
1
BOTH_EQUAL =
0
COMPARERS =
{}
PATTERNS_RE =

/(?<=^|s)[d.]+||.?/ /(?<=^|s)[d.]+||[^d.-]|+/

/\d+(?:\.\d+){2,}|(?:(?<=^|\s)[-])?\d+(?:\.\d+)?|.+?/
NUMERIC_RE =
/[-]?\d+(\.\d+)?/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value, index) ⇒ AtomSorter

Returns a new instance of AtomSorter.



22
23
24
# File 'lib/trusty/sorting/atom_sorter.rb', line 22

def initialize(value, index)
  @value, @index = value, index
end

Instance Attribute Details

#indexObject (readonly)

Returns the value of attribute index.



20
21
22
# File 'lib/trusty/sorting/atom_sorter.rb', line 20

def index
  @index
end

#valueObject (readonly)

Returns the value of attribute value.



20
21
22
# File 'lib/trusty/sorting/atom_sorter.rb', line 20

def value
  @value
end

Class Method Details

.add_comparer(left_type, right_type, &comparer) ⇒ Object



58
59
60
# File 'lib/trusty/sorting/atom_sorter.rb', line 58

def add_comparer(left_type, right_type, &comparer)
  COMPARERS[comparer_key_for(left_type, right_type)] = comparer_builder(left_type, right_type, &comparer)
end

.compare_values(left_value, right_value) ⇒ Object



33
34
35
36
37
38
39
40
41
# File 'lib/trusty/sorting/atom_sorter.rb', line 33

def compare_values(left_value, right_value)
  if left_value.class == right_value.class
    left_value <=> right_value
  elsif comparer = COMPARERS[comparer_key_for(left_value.class, right_value.class)]
    comparer.call(left_value, right_value)
  else
    raise "No comparer defined for #{left_value.class} <=> #{right_value.class}"
  end
end

.parse(string) ⇒ Object

Loosely based on stackoverflow.com/a/4079031



44
45
46
47
48
49
50
51
52
# File 'lib/trusty/sorting/atom_sorter.rb', line 44

def parse(string)
  string.scan(PATTERNS_RE).each_with_index.map do |atom, index|
    if    !atom.match(NUMERIC_RE) then  new(normalize_string(atom), index)
    elsif !atom.include?('.')     then  new(atom.to_i, index)
    elsif atom.include?('-')      then  new(atom.to_f, index)
    else                                new(Atoms::Version.new(atom), index)
    end
  end
end

.sort(list) ⇒ Object



54
55
56
# File 'lib/trusty/sorting/atom_sorter.rb', line 54

def sort(list)
  list.sort_by{ |item| parse(item) }
end

Instance Method Details

#<=>(other) ⇒ Object



26
27
28
29
30
# File 'lib/trusty/sorting/atom_sorter.rb', line 26

def <=>(other)
  other.is_a?(self.class) || raise("#{self.class} can only compare with classes of the same kind")

  self.class.compare_values(self.value, other.value)
end