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)