Ruby 2.7 adds supports for Comparable#clamp with a range


Clamp method was added to Comparable module in Ruby 2.4.

Comparable#clamp

The method is used to clamp an object within a specific range of values.

20.clamp(0, 5)
=> 5

20.clamp(0, 50)
=> 20

20.clamp(30, 50)
=> 30

Similarly, strings can also be clamped within a range.

"p".clamp("a", "z")
=> "p"
 
"p".clamp("s", "z")
=> "s"

"p".clamp("a", "g")
=> "g"

"king".clamp("kingdom", "kingship")
=> "kingdom"

One way to use clamping effectively is to define the minimum and maximum values for the globally used entities in configurations or constants and use them app-wide.

Example,

We have a constant to define range for the score

SCORE_RANGE = (1..10)

In order to clamp the input score value within score range we need to do,

input_score = 15
input_score.clamp(SCORE_RANGE.min, SCORE_RANGE.max)
=> 10

Comparable#clamp with a Range argument

Comparable#clamp accepts a Range argument with Ruby 2.7

The above score clamping can happen with,

input_score = 15
input_score.clamp(SCORE_RANGE)
=> 10

Both numbers and strings can be clamped with a Range argument,

20.clamp(0..5)
=> 5

20.clamp(0..50)
=> 20

20.clamp(30..50)
=> 30

"p".clamp("a".."z")
=> "p"

"p".clamp("s".."z")
=> "s"

"p".clamp("a".."g")
=> "g"
 
"king".clamp("kingdom".."kingship")
=> "kingdom"

Comparable#clamp with a beginless and endless inclusive range(..)

When range is created using .., it runs from the beginning to the end inclusively.

20.clamp(10..)
=> 20

20.clamp(30..)
=> 30

20.clamp(..10)
=> 10

20.clamp(..30)
=> 20

Comparable#clamp with a beginless and endless end exclusive range(...)

When range is created with ..., it excludes the end value.

With endless range:

20.clamp(10...)
=> 20

20.clamp(30...)
=> 30

With beginless range:

20.clamp(...10)
=> ArgumentError (cannot clamp with an exclusive range)

20.clamp(...50)
=> ArgumentError (cannot clamp with an exclusive range)

Join Our Newsletter