# The Comparable mixin is used by classes whose objects may be ordered. The # class must define the `<=>` operator, which compares the receiver against # another object, returning a value less than 0, returning 0, or returning a # value greater than 0, depending on whether the receiver is less than, equal # to, or greater than the other object. If the other object is not comparable # then the `<=>` operator should return `nil`. Comparable uses `<=>` to # implement the conventional comparison operators (`<`, `<=`, `==`, `>=`, and # `>`) and the method `between?`. # # class SizeMatters # include Comparable # attr :str # def <=>(other) # str.size <=> other.str.size # end # def initialize(str) # @str = str # end # def inspect # @str # end # end # # s1 = SizeMatters.new("Z") # s2 = SizeMatters.new("YY") # s3 = SizeMatters.new("XXX") # s4 = SizeMatters.new("WWWW") # s5 = SizeMatters.new("VVVVV") # # s1 < s2 #=> true # s4.between?(s1, s3) #=> false # s4.between?(s3, s5) #=> true # [ s3, s2, s5, s4, s1 ].sort #=> [Z, YY, XXX, WWWW, VVVVV] # module Comparable : _WithSpaceshipOperator # Compares two objects based on the receiver's `<=>` method, returning true if # it returns a value less than 0. # def <: (untyped other) -> bool # Compares two objects based on the receiver's `<=>` method, returning true if # it returns a value less than or equal to 0. # def <=: (untyped other) -> bool # Compares two objects based on the receiver's `<=>` method, returning true if # it returns 0. Also returns true if *obj* and *other* are the same object. # def ==: (untyped other) -> bool # Compares two objects based on the receiver's `<=>` method, returning true if # it returns a value greater than 0. # def >: (untyped other) -> bool # Compares two objects based on the receiver's `<=>` method, returning true if # it returns a value greater than or equal to 0. # def >=: (untyped other) -> bool # Returns `false` if *obj* `<=>` *min* is less than zero or if *obj* `<=>` *max* # is greater than zero, `true` otherwise. # # 3.between?(1, 5) #=> true # 6.between?(1, 5) #=> false # 'cat'.between?('ant', 'dog') #=> true # 'gnu'.between?('ant', 'dog') #=> false # def between?: (untyped min, untyped max) -> bool # In `(min, max)` form, returns *min* if *obj* `<=>` *min* is less than zero, # *max* if *obj* `<=>` *max* is greater than zero, and *obj* otherwise. # # 12.clamp(0, 100) #=> 12 # 523.clamp(0, 100) #=> 100 # -3.123.clamp(0, 100) #=> 0 # # 'd'.clamp('a', 'f') #=> 'd' # 'z'.clamp('a', 'f') #=> 'f' # # In `(range)` form, returns *range.begin* if *obj* `<=>` *range.begin* is less # than zero, *range.end* if *obj* `<=>` *range.end* is greater than zero, and # *obj* otherwise. # # 12.clamp(0..100) #=> 12 # 523.clamp(0..100) #=> 100 # -3.123.clamp(0..100) #=> 0 # # 'd'.clamp('a'..'f') #=> 'd' # 'z'.clamp('a'..'f') #=> 'f' # # If *range.begin* is `nil`, it is considered smaller than *obj*, and if # *range.end* is `nil`, it is considered greater than *obj*. # # -20.clamp(0..) #=> 0 # 523.clamp(..100) #=> 100 # # When *range.end* is excluded and not `nil`, an exception is raised. # # 100.clamp(0...100) # ArgumentError # def clamp: [A, B] (A min, B max) -> (self | A | B) | [A] (Range[A]) -> (self | A) end # This interface defines the condition for Comparable mixin. # interface Comparable::_WithSpaceshipOperator # `<=>` operator must return Integer or `nil`. # If `other` is greater than `self`, it returns a positive Integer. # If `other` equals to `self`, it returns zero. # If `other` is less than `self`, it returns a positive Integer. # If no comparison is defined with `other` and `self`, it returns `nil`. # def <=>: (untyped other) -> Integer? end