Actions
Feature #14784
closedComparable#clamp with a range
Status:
Closed
Assignee:
-
Target version:
-
Description
Proposal
Allow "one-sided" clamp
to limit only upper bound (and, ideally, only lower too).
Proposed implementation: allow clamp(begin..end)
call sequence (without deprecating clamp(begin, end)
), to take advantage from open-ended ranges with clamp(begin..)
.
Reasoning about range
I looked through #clamp
discussion, but couldn't find there why syntax clamp(b, e)
was preferred to clamp(b..e)
. The only one I could think of is possible confuse of how clamp(b..e)
and clamp(b...e)
behaviors should differ.
The problem becomes more important with the introduction of open-ended ranges. I believe this is pretty natural:
some_calculation.clamp(0..) # now, I use clamp(0, Float::INFINITY)
timestamp.clamp(Date.today..) # now, I typically use clamp(Date.today..INFINITE_FUTURE_DATE) with custom defined constant
Counter-arguments:
- This is "one-sided", you can't do
clamp(..Date.today)
. To this I can answer than from my experience "clamping only minimum" is more frequent, and if you need to clamp only maximum, most of the time there is some "reasonable minumum". Another idea is that maybe this is a proof why "start-less" ranges are necessary, after all, doubted here - Why not just leave current
clamp(b, e)
and allowclamp(b)
? Answer: because when you seeclamp(10)
, is itclamp(10, nil)
, orclamp(nil, 10)
(yes, logically it is the first argument that is left, but from readability point of view it is not that obvious). Possible alternative:clamp(min: 0, max: 10)
, where you can omit any of two. - Why do you need one-sided clamp at all? Because alternatives is much more wordy, making reader think:
# with clamp
chain.of.calculations.clamp(0..)
# without clamp
v = chain.of.calculations
v < 0 ? 0 : v
# or, with yield_self (renamed to then)
chain.of.calculations.then { |v| v < 0 ? 0 : v }
Both alternatives "without #clamp
" shows intentions much less clear.
Actions
Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0