Using Comparable#clamp to limit a value to within a range
This was the tip of the week in the Jan 28, 2021 Ruby Weekly Newsletter.
Forcing a value to fall within a range became a whole lot easier when Ruby 2.4 introduced Comparable#clamp
.
Comparable#clamp
takes min
and max
arguments. If the value we’re “clamping” is within the min
and max
, Comparable#clamp
returns the value unchanged. Otherwise, if the value is less than min
, Comparable#clamp
returns min
, and if the value is greater than max
, Comparable#clamp
returns max
:
1.clamp(0,3)
=> 1
1.clamp(2,3)
=> 2
"jemma".clamp("a", "z")
=> "jemma"
"jemma".clamp("a", "j")
=> "j"
And then, just when we were getting really excited about Comparable#clamp
, Ruby 2.7 gave us even more to work with! As of Ruby 2.7, clamp can also take an inclusive ..
(not exclusive ...
) range of values.
Notably, nil can be within this range. val.clamp(..max)
will be the equivalent of taking the minimum of val
and max
. And vice versa. Let’s take a look:
1.clamp(2..3)
=> 2
1.clamp(..3)
=> 1
And lastly, just as a reminder, the Comparable mixin is used by classes whose objects can be comparaed and therefore ordered. If you’d like to have clamping work for a class you’ve written, be sure to include Comparable
and define the <=>
operator.