File: compar.rb

package info (click to toggle)
mruby 3.4.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,584 kB
  • sloc: ansic: 51,933; ruby: 29,510; yacc: 7,077; cpp: 517; makefile: 51; sh: 42
file content (75 lines) | stat: -rw-r--r-- 2,056 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
module Comparable
  ##
  #  call-seq:
  #    obj.clamp(min, max) ->  obj
  #    obj.clamp(range)    ->  obj
  #
  # In <code>(min, max)</code> form, returns _min_ if _obj_
  # <code><=></code> _min_ is less than zero, _max_ if _obj_
  # <code><=></code> _max_ is greater than zero, and _obj_
  # otherwise.
  #
  #    12.clamp(0, 100)         #=> 12
  #    523.clamp(0, 100)        #=> 100
  #    -3.123.clamp(0, 100)     #=> 0
  #
  #    'd'.clamp('a', 'f')      #=> 'd'
  #    'z'.clamp('a', 'f')      #=> 'f'
  #
  # In <code>(range)</code> form, returns _range.begin_ if _obj_
  # <code><=></code> _range.begin_ is less than zero, _range.end_
  # if _obj_ <code><=></code> _range.end_ is greater than zero, and
  # _obj_ otherwise.
  #
  #    12.clamp(0..100)         #=> 12
  #    523.clamp(0..100)        #=> 100
  #    -3.123.clamp(0..100)     #=> 0
  #
  #    'd'.clamp('a'..'f')      #=> 'd'
  #    'z'.clamp('a'..'f')      #=> 'f'
  #
  # If _range.begin_ is +nil+, it is considered smaller than _obj_,
  # and if _range.end_ is +nil+, it is considered greater than
  # _obj_.
  #
  #    -20.clamp(0..)           #=> 0
  #    523.clamp(..100)         #=> 100
  #
  # When _range.end_ is excluded and not +nil+, an exception is
  # raised.
  #
  #     100.clamp(0...100)       # ArgumentError
  #
  def clamp(min, max=nil)

    if max.nil?
      if min.kind_of?(Range)
        max = min.end
        if !max.nil? && min.exclude_end?
          raise ArgumentError, "cannot clamp with an exclusive range"
        end
        min = min.begin
      end
    end

    if !min.nil? && !max.nil?
      cmp = min <=> max
      if cmp.nil?
        raise ArgumentError, "comparison of #{min.class} with #{max.class} failed"
      elsif cmp > 0
        raise ArgumentError, "min argument must be smaller than max argument"
      end
    end

    unless min.nil?
      cmp = self <=> min
      return self if cmp == 0
      return min if cmp < 0
    end
    unless max.nil?
      cmp = self <=> max
      return max if cmp > 0
    end
    return self
  end
end