Module: Comparable
- Included in:
- File::Stat, Numeric, String, Symbol, Time
- Defined in:
- compar.c
Overview
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]
Instance Method Summary collapse
-
#<(other) ⇒ Boolean
Compares two objects based on the receiver’s
<=>method, returning true if it returns a value less than 0. -
#<=(other) ⇒ Boolean
Compares two objects based on the receiver’s
<=>method, returning true if it returns a value less than or equal to 0. -
#==(other) ⇒ Boolean
Compares two objects based on the receiver’s
<=>method, returning true if it returns 0. -
#>(other) ⇒ Boolean
Compares two objects based on the receiver’s
<=>method, returning true if it returns a value greater than 0. -
#>=(other) ⇒ Boolean
Compares two objects based on the receiver’s
<=>method, returning true if it returns a value greater than or equal to 0. -
#between?(min, max) ⇒ Boolean
Returns
falseif obj<=>min is less than zero or if obj<=>max is greater than zero,trueotherwise. -
#clamp(*args) ⇒ Object
In
(min, max)form, returns min if obj<=>min is less than zero, max if obj<=>max is greater than zero, and obj otherwise.
Instance Method Details
#<(other) ⇒ Boolean
Compares two objects based on the receiver’s <=> method, returning true if it returns a value less than 0.
132 133 134 135 136 137 |
# File 'compar.c', line 132 static VALUE cmp_lt(VALUE x, VALUE y) { if (cmpint(x, y) < 0) return Qtrue; return Qfalse; } |
#<=(other) ⇒ Boolean
Compares two objects based on the receiver’s <=> method, returning true if it returns a value less than or equal to 0.
147 148 149 150 151 152 |
# File 'compar.c', line 147 static VALUE cmp_le(VALUE x, VALUE y) { if (cmpint(x, y) <= 0) return Qtrue; return Qfalse; } |
#==(other) ⇒ Boolean
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.
75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'compar.c', line 75 static VALUE cmp_equal(VALUE x, VALUE y) { VALUE c; if (x == y) return Qtrue; c = rb_exec_recursive_paired_outer(cmp_eq_recursive, x, y, y); if (NIL_P(c)) return Qfalse; if (rb_cmpint(c, x, y) == 0) return Qtrue; return Qfalse; } |
#>(other) ⇒ Boolean
Compares two objects based on the receiver’s <=> method, returning true if it returns a value greater than 0.
102 103 104 105 106 107 |
# File 'compar.c', line 102 static VALUE cmp_gt(VALUE x, VALUE y) { if (cmpint(x, y) > 0) return Qtrue; return Qfalse; } |
#>=(other) ⇒ Boolean
Compares two objects based on the receiver’s <=> method, returning true if it returns a value greater than or equal to 0.
117 118 119 120 121 122 |
# File 'compar.c', line 117 static VALUE cmp_ge(VALUE x, VALUE y) { if (cmpint(x, y) >= 0) return Qtrue; return Qfalse; } |
#between?(min, max) ⇒ Boolean
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
169 170 171 172 173 174 175 |
# File 'compar.c', line 169 static VALUE cmp_between(VALUE x, VALUE min, VALUE max) { if (cmpint(x, min) < 0) return Qfalse; if (cmpint(x, max) > 0) return Qfalse; return Qtrue; } |
#clamp(min, max) ⇒ Object #clamp(range) ⇒ Object
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
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'compar.c', line 219 static VALUE cmp_clamp(int argc, VALUE *argv, VALUE x) { VALUE min, max; int c, excl = 0; if (rb_scan_args(argc, argv, "11", &min, &max) == 1) { VALUE range = min; if (!rb_range_values(range, &min, &max, &excl)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Range)", rb_builtin_class_name(range)); } if (!NIL_P(max)) { if (excl) rb_raise(rb_eArgError, "cannot clamp with an exclusive range"); if (!NIL_P(min) && cmpint(min, max) > 0) goto arg_error; } } else if (cmpint(min, max) > 0) { arg_error: rb_raise(rb_eArgError, "min argument must be smaller than max argument"); } if (!NIL_P(min)) { c = cmpint(x, min); if (c == 0) return x; if (c < 0) return min; } if (!NIL_P(max)) { c = cmpint(x, max); if (c > 0) return max; } return x; } |