# module Comparable(T)

##
Overview

The `Comparable` mixin is used by classes whose objects may be ordered.

Including types must provide an `<=>` method, which compares the receiver against another object, returning:

- a negative number if `self` is less than the other object
- a positive number if `self` is greater than the other object
- `0` if `self` is equal to the other object
- `nil` if `self` and the other object are not comparable

`Comparable` uses `<=>` to implement the conventional comparison operators (`<`, `<=`, `#==`, `>=`, and `>`). All of these return `false` when `<=>` returns `nil`.

Note that returning `nil` is only useful when defining a partial comparable relationship. One such example is float values: they are generally comparable, except for `NaN`. If none of the values of a type are comparable between each other, `Comparable` shouldn't be included.

NOTE When `nil` is returned from `<=>`, `Array#sort` and related sorting methods will perform slightly slower.

##
Direct including types

- Array(T)
- BigDecimal
- BigFloat
- BigInt
- BigRational
- Char
- Enum
- Float
- Int
- Number
- Path
- Pointer(T)
- SemanticVersion
- SemanticVersion::Prerelease
- Slice(T)
- StaticArray(T, N)
- String
- Symbol
- Time
- Time::Span
- Tuple(*T)
- UUID

##
Defined in:

comparable.cr

##
Instance Method Summary

- #<(other : T) : Bool

  Compares this object to other based on the receiver’s `<=>` method, returning `true` if it returns a negative number.

- #<=(other : T)

  Compares this object to other based on the receiver’s `<=>` method, returning `true` if it returns a value equal or less then `0`.

- #<=>(other : T)

  The comparison operator.

- #==(other : T)

  Compares this object to other based on the receiver’s `<=>` method, returning `true` if it returns `0`.

- #>(other : T) : Bool

  Compares this object to other based on the receiver’s `<=>` method, returning `true` if it returns a value greater then `0`.

- #>=(other : T)

  Compares this object to other based on the receiver’s `<=>` method, returning `true` if it returns a value equal or greater than `0`.

- #clamp(min, max)

  Clamps a value between min and max.

- #clamp(range : Range)

  Clamps a value within range.

##
Instance Method Detail

def <(other : T) : Bool #

Compares this object to other based on the receiver’s `<=>` method, returning `true` if it returns a negative number.

def <=(other : T) #

Compares this object to other based on the receiver’s `<=>` method, returning `true` if it returns a value equal or less then `0`.

abstract def <=>(other : T) #

The comparison operator. Returns `0` if the two objects are equal, a negative number if this object is considered less than other, a positive number if this object is considered greater than other, or `nil` if the two objects are not comparable.

Subclasses define this method to provide class-specific ordering.

The comparison operator is usually used to sort values:

    # Sort in a descending way:
    [3, 1, 2].sort { |x, y| y <=> x } # => [3, 2, 1]

    # Sort in an ascending way:
    [3, 1, 2].sort { |x, y| x <=> y } # => [1, 2, 3]

def ==(other : T) #

Compares this object to other based on the receiver’s `<=>` method, returning `true` if it returns `0`.

Also returns `true` if this and other are the same object.

def >(other : T) : Bool #

Compares this object to other based on the receiver’s `<=>` method, returning `true` if it returns a value greater then `0`.

def >=(other : T) #

Compares this object to other based on the receiver’s `<=>` method, returning `true` if it returns a value equal or greater than `0`.

def clamp(min, max) #

Clamps a value between min and max.

    5.clamp(10, 100)   # => 10
    50.clamp(10, 100)  # => 50
    500.clamp(10, 100) # => 100

    5.clamp(10, nil)  # => 10
    50.clamp(10, nil) # => 50

    5.clamp(nil, 10)  # => 5
    50.clamp(nil, 10) # => 10

def clamp(range : Range) #

Clamps a value within range.

    5.clamp(10..100)   # => 10
    50.clamp(10..100)  # => 50
    500.clamp(10..100) # => 100

    5.clamp(10..)  # => 10
    50.clamp(10..) # => 50

    5.clamp(..10)  # => 5
    50.clamp(..10) # => 10