Ruby 2.7 adds supports for Comparable#clamp with a range

1 minute read

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: