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
false
if obj<=>
min is less than zero or if obj<=>
max is greater than zero,true
otherwise. -
#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.
135 136 137 138 139 140 |
# File 'compar.c', line 135
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.
150 151 152 153 154 155 |
# File 'compar.c', line 150
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.
78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'compar.c', line 78
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.
105 106 107 108 109 110 |
# File 'compar.c', line 105
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.
120 121 122 123 124 125 |
# File 'compar.c', line 120
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
172 173 174 175 176 177 178 |
# File 'compar.c', line 172
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
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 252 253 254 |
# File 'compar.c', line 222
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;
}
|