Guest User

Untitled

a guest
Feb 20th, 2018
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.57 KB | None | 0 0
  1. # A version number is a kind of number
  2. class VersionNumber < Numeric
  3.  
  4. attr_reader :parts, :labels, :literal
  5.  
  6. # Create a new VersionNumber
  7. def initialize(literal=nil)
  8. @parts = [0,0,0] # Numeric parts
  9. @labels = ['major', 'minor', 'patch'] # Alpha parts
  10. @literal = literal.to_s # The original literal
  11. case literal
  12. when String
  13. part = 0
  14. previous_part_was_label = false
  15. # Tokenize the string and calculate the parts
  16. literal.scan(/(?:\d+)|(?:[A-z]+)|(?:[^\w\d]+)/).each do |token|
  17. case token
  18. when /\d/ # Numeric part
  19. @parts[part] = token.to_i # We can do this because Ruby knows to expand the array to [token], otherwise we'd have to use push
  20. part += 1
  21. previous_part_was_label = false
  22. when /\w/ # Alpha part : this works because numerics are matched by the first rule
  23. if previous_part_was_label # If there were two alpha components in a row
  24. @parts[part] = 0 # Default to zero
  25. part += 1
  26. end
  27. @labels[part] = token
  28. previous_part_was_label = true
  29. end
  30. end
  31. when Array
  32. @parts = literal.select { |i| i.to_s =~ /^\d+$/ }
  33. when Hash
  34. @parts = literal[:parts] if literal[:parts]
  35. @labels = literal[:labels] if literal[:labels]
  36. if literal[:literal]
  37. @literal = literal[:literal]
  38. else
  39. @literal = to_s
  40. end
  41. when VersionNumber
  42. @parts = literal.parts
  43. @labels = literal.labels
  44. @literal = literal.literal
  45. when Numeric
  46. @parts = @literal.split(//).select { |i| i =~ /\d/ }.collect { |i| i.to_i }
  47. else
  48. raise ArgumentError.new("Bad type for VersionNumber.new : #{literal.class}")
  49. end
  50. end
  51.  
  52. # Type conversions
  53.  
  54. def to_s
  55. rtrn = ''
  56. @parts.each_with_index do |part, i|
  57. unless !@labels[i] or (i == 0 and @labels[0] == 'major') or (i == 1 and @labels[1] == 'minor' or i == 2 and @labels[2] == 'patch')
  58. rtrn << '-' + @labels[i]
  59. else
  60. rtrn << '.' unless i == 0
  61. end
  62. rtrn << part.to_s
  63. end
  64. rtrn
  65. end
  66.  
  67. def to_f
  68. rtrn = 0.0
  69. @parts.each_with_index do |part, i|
  70. rtrn += part/(10.0**i)
  71. end
  72. rtrn
  73. end
  74.  
  75. def to_i
  76. @parts[0]
  77. end
  78.  
  79. def dup
  80. VersionNumber.new(self)
  81. end
  82.  
  83. # Math
  84.  
  85. def /(v)
  86. VersionNumber.new(to_f/v)
  87. end
  88.  
  89. def %(v)
  90. VersionNumber.new(to_f % v)
  91. end
  92.  
  93. def +(v)
  94. v = VersionNumber.new(v)
  95. parts = [0,0,0]
  96. @parts.each_with_index do |part, i|
  97. parts[i] = part + v.parts[i].to_i
  98. end
  99. VersionNumber.new({ :parts => parts, :labels => @labels })
  100. end
  101.  
  102. def -(v)
  103. v = VersionNumber.new(v)
  104. parts = [0,0,0]
  105. @parts.each_with_index do |part, i|
  106. parts[i] = part - v.parts[i].to_i
  107. if parts[i] < 0
  108. parts[i-1] += parts[i]
  109. parts[i] = 0
  110. end
  111. end
  112. VersionNumber.new({ :parts => parts, :labels => @labels })
  113. end
  114.  
  115. # Comparison
  116.  
  117. def <=>(v)
  118. v = VersionNumber.new(v)
  119. return 0 if parts == v.parts
  120. rtrn = 0
  121. @parts.each_with_index do |part, i|
  122. if rtrn > 0
  123. rtrn += part - v.parts[i].to_i if part - v.parts[i].to_i > 0
  124. elsif rtrn < 0
  125. rtrn += part - v.parts[i].to_i if part - v.parts[i].to_i < 0
  126. else
  127. rtrn += part - v.parts[i].to_i
  128. end
  129. end
  130. rtrn
  131. end
  132.  
  133. def ===(v)
  134. v = VersionNumber.new(v)
  135. parts == v.parts
  136. labels == v.labels
  137. literal == v.literal
  138. end
  139.  
  140. def nonzero?
  141. sum = 0
  142. @parts.each do |part|
  143. sum += part
  144. end
  145. sum != 0
  146. end
  147.  
  148. def zero?
  149. not nonzero?
  150. end
  151.  
  152. # Positive, non-imaginary number
  153. def arg; 0; end
  154. alias angle arg
  155. def conjugate; self; end
  156. alias conj conjugate
  157. alias real conjugate
  158. def image; 0; end
  159. alias imag image
  160.  
  161. end
Add Comment
Please, Sign In to add comment