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.