Class: RangeComponentAttributes::RangeWrapper

Inherits:
Object
  • Object
show all
Defined in:
lib/range_component_attributes/range_wrapper.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(lower_type_converter:, upper_type_converter:, exclude_end: true, lower: nil, upper: nil, range: nil, crossed_bounds_message: "must be less than upper bound") ⇒ RangeWrapper

Returns a new instance of RangeWrapper.

Raises:

  • (ArgumentError)


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
# File 'lib/range_component_attributes/range_wrapper.rb', line 7

def initialize(
  # Range type
  lower_type_converter:,
  upper_type_converter:,
  exclude_end: true,

  # Initial values
  lower: nil,
  upper: nil,
  range: nil,

  crossed_bounds_message: "must be less than upper bound"
)
  raise ArgumentError, "lower/upper and range are mutually exclusive" if (lower || upper) && range

  @errors = {}
  @lower_type_converter = lower_type_converter
  @upper_type_converter = upper_type_converter
  @exclude_end = exclude_end
  @crossed_bounds_message = crossed_bounds_message

  @range = nil
  @lower = nil
  @upper = nil

  if range
    self.range = range
  else
    self.lower = lower
    self.upper = upper
  end
end

Instance Attribute Details

#errorsObject (readonly)

Returns the value of attribute errors.



5
6
7
# File 'lib/range_component_attributes/range_wrapper.rb', line 5

def errors
  @errors
end

Instance Method Details

#lowerObject



60
61
62
# File 'lib/range_component_attributes/range_wrapper.rb', line 60

def lower
  @lower
end

#lower=(x) ⇒ Object



64
65
66
67
68
69
70
71
72
# File 'lib/range_component_attributes/range_wrapper.rb', line 64

def lower=(x)
  @lower = begin
    @lower_type_converter.(x).tap { errors.delete(:lower) }
  rescue TypeConversionError => e
    errors[:lower] = "is not a #{e.target_type}"
    x
  end
  convert_lower_and_upper_to_range
end

#rangeObject

Raises:



40
41
42
43
# File 'lib/range_component_attributes/range_wrapper.rb', line 40

def range
  raise InvalidRangeError unless valid?
  @range
end

#range=(x) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/range_component_attributes/range_wrapper.rb', line 45

def range=(x)
  if x
    @lower = x.begin
    @upper = x.end
    if x.exclude_end? != @exclude_end && @upper.respond_to?(:next)
      @upper += x.exclude_end? ? -1 : 1
    end
    convert_lower_and_upper_to_range
  else
    @lower = nil
    @upper = nil
    @range = nil
  end
end

#upperObject



74
75
76
# File 'lib/range_component_attributes/range_wrapper.rb', line 74

def upper
  @upper
end

#upper=(x) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/range_component_attributes/range_wrapper.rb', line 78

def upper=(x)
  @upper = begin
    @upper_type_converter.(x).tap { errors.delete(:upper) }
  rescue TypeConversionError => e
    errors[:upper] = "is not a #{e.target_type}"
    x
  end

  # An error on lower might have been caused by crossed bounds. So reassign lower to itself to recheck.
  if errors[:lower].present?
    self.lower = lower
  end

  convert_lower_and_upper_to_range
end

#valid?Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/range_component_attributes/range_wrapper.rb', line 94

def valid?
  errors.empty?
end