aixm 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +14 -0
  4. data/README.md +3 -1
  5. data/lib/aixm/a.rb +29 -15
  6. data/lib/aixm/association.rb +2 -1
  7. data/lib/aixm/classes.rb +4 -0
  8. data/lib/aixm/component/address.rb +15 -9
  9. data/lib/aixm/component/approach_lighting.rb +28 -25
  10. data/lib/aixm/component/fato.rb +38 -26
  11. data/lib/aixm/component/frequency.rb +32 -20
  12. data/lib/aixm/component/geometry/arc.rb +16 -3
  13. data/lib/aixm/component/geometry/border.rb +8 -1
  14. data/lib/aixm/component/geometry/circle.rb +14 -2
  15. data/lib/aixm/component/geometry/point.rb +8 -1
  16. data/lib/aixm/component/geometry/rhumb_line.rb +8 -1
  17. data/lib/aixm/component/geometry.rb +20 -10
  18. data/lib/aixm/component/helipad.rb +41 -20
  19. data/lib/aixm/component/layer.rb +31 -20
  20. data/lib/aixm/component/lighting.rb +22 -24
  21. data/lib/aixm/component/runway.rb +32 -25
  22. data/lib/aixm/component/service.rb +11 -17
  23. data/lib/aixm/component/surface.rb +47 -14
  24. data/lib/aixm/component/timesheet.rb +178 -0
  25. data/lib/aixm/component/timetable.rb +32 -13
  26. data/lib/aixm/component/vasis.rb +36 -6
  27. data/lib/aixm/component/vertical_limit.rb +26 -4
  28. data/lib/aixm/component.rb +4 -1
  29. data/lib/aixm/concerns/hash_equality.rb +21 -0
  30. data/lib/aixm/concerns/intensity.rb +30 -0
  31. data/lib/aixm/concerns/marking.rb +21 -0
  32. data/lib/aixm/concerns/remarks.rb +21 -0
  33. data/lib/aixm/concerns/timetable.rb +22 -0
  34. data/lib/aixm/d.rb +20 -14
  35. data/lib/aixm/document.rb +22 -5
  36. data/lib/aixm/f.rb +29 -17
  37. data/lib/aixm/feature/airport.rb +91 -45
  38. data/lib/aixm/feature/airspace.rb +28 -5
  39. data/lib/aixm/feature/navigational_aid/designated_point.rb +8 -1
  40. data/lib/aixm/feature/navigational_aid/dme.rb +12 -2
  41. data/lib/aixm/feature/navigational_aid/marker.rb +9 -2
  42. data/lib/aixm/feature/navigational_aid/ndb.rb +15 -3
  43. data/lib/aixm/feature/navigational_aid/vor.rb +20 -3
  44. data/lib/aixm/feature/navigational_aid.rb +29 -20
  45. data/lib/aixm/feature/obstacle.rb +105 -29
  46. data/lib/aixm/feature/obstacle_group.rb +3 -7
  47. data/lib/aixm/feature/organisation.rb +23 -14
  48. data/lib/aixm/feature/unit.rb +23 -11
  49. data/lib/aixm/feature.rb +23 -4
  50. data/lib/aixm/memoize.rb +3 -3
  51. data/lib/aixm/p.rb +20 -14
  52. data/lib/aixm/payload_hash.rb +5 -2
  53. data/lib/aixm/r.rb +15 -12
  54. data/lib/aixm/refinements.rb +42 -2
  55. data/lib/aixm/schedule/date.rb +181 -0
  56. data/lib/aixm/schedule/day.rb +114 -0
  57. data/lib/aixm/schedule/time.rb +255 -0
  58. data/lib/aixm/shortcuts.rb +3 -0
  59. data/lib/aixm/version.rb +1 -1
  60. data/lib/aixm/w.rb +20 -13
  61. data/lib/aixm/xy.rb +36 -25
  62. data/lib/aixm/z.rb +29 -17
  63. data/lib/aixm.rb +13 -0
  64. data.tar.gz.sig +0 -0
  65. metadata +22 -13
  66. metadata.gz.sig +0 -0
@@ -43,6 +43,7 @@ module AIXM
43
43
  class Obstacle < Feature
44
44
  include AIXM::Association
45
45
  include AIXM::Memoize
46
+ include AIXM::Concerns::Remarks
46
47
 
47
48
  public_class_method :new
48
49
 
@@ -67,63 +68,138 @@ module AIXM
67
68
  # @return [AIXM::Feature::ObstacleGroup] group this obstacle belongs to
68
69
  belongs_to :obstacle_group
69
70
 
70
- # @return [String] full name
71
+ # Full name.
72
+ #
73
+ # @overload name
74
+ # @return [String]
75
+ # @overload name=(value)
76
+ # @param value [String]
71
77
  attr_reader :name
72
78
 
73
- # @return [Symbol] type of obstacle
79
+ # Type of obstacle.
80
+ #
81
+ # @overload type
82
+ # @return [Symbol] any of {TYPES}
83
+ # @overload type=(value)
84
+ # @param value [Symbol] any of {TYPES}
74
85
  attr_reader :type
75
86
 
76
- # @return [AIXM::XY] circular base center point
87
+ # Circular base center point.
88
+ #
89
+ # @overload xy
90
+ # @return [AIXM::XY]
91
+ # @overload xy=(value)
92
+ # @param value [AIXM::XY]
77
93
  attr_reader :xy
78
94
 
79
- # @return [AIXM::D] circular base radius
95
+ # Circular base radius.
96
+ #
97
+ # @overload radius
98
+ # @return [AIXM::D]
99
+ # @overload radius=(value)
100
+ # @param value [AIXM::D]
80
101
  attr_reader :radius
81
102
 
82
- # @return [AIXM::Z] elevation of the top point in +:qnh+
103
+ # Elevation of the top point in +:qnh+.
104
+ #
105
+ # @overload z
106
+ # @return [AIXM::Z]
107
+ # @overload z=(value)
108
+ # @param value [AIXM::Z]
83
109
  attr_reader :z
84
110
 
85
- # @return [Boolean, nil] lighting (e.g. strobes)
86
- # true => lighting present, false => no lighting, nil => unknown
111
+ # Presence of lighting (e.g. strobes).
112
+ #
113
+ # @overload lighting
114
+ # @return [Boolean, nil] +nil+ means unknown
115
+ # @overload lighting=(value)
116
+ # @param value [Boolean, nil] +nil+ means unknown
87
117
  attr_reader :lighting
88
118
 
89
- # @return [String, nil] detailed description of the lighting
119
+ # Detailed description of the lighting.
120
+ #
121
+ # @overload lighting_remarks
122
+ # @return [String, nil]
123
+ # @overload lighting_remarks=(value)
124
+ # @param value [String, nil]
90
125
  attr_reader :lighting_remarks
91
126
 
92
- # @return [Boolean, nil] marking (e.g. red/white paint)
93
- # true => marking present, false => no marking, nil => unknown
127
+ # Presence of marking (e.g. red/white paint).
128
+ #
129
+ # @overload marking
130
+ # @return [Boolean, nil] +nil+ means unknown
131
+ # @overload marking=(value)
132
+ # @param value [Boolean, nil] +nil+ means unknown
94
133
  attr_reader :marking
95
134
 
96
- # @return [String, nil] detailed description of the marking
135
+ # Detailed description of the marking.
136
+ #
137
+ # @overload marking_remarks
138
+ # @return [String nil]
139
+ # @overload marking_remarks=(value)
140
+ # @param value [String, nil]
97
141
  attr_reader :marking_remarks
98
142
 
99
- # @return [AIXM::D, nil] height from ground to top point
143
+ # Height from ground to top point.
144
+ #
145
+ # @overload height
146
+ # @return [AIXM::D, nil]
147
+ # @overload height=(value)
148
+ # @param value [AIXM::D, nil]
100
149
  attr_reader :height
101
150
 
102
- # @return [Boolean, nil] height accuracy
103
- # true => height measured, false => height estimated, nil => unknown
151
+ # Height accuracy.
152
+ #
153
+ # @overload height_accurate
154
+ # @return [Boolean, nil] +nil+ means unknown
155
+ # @overload height_accurate=(value)
156
+ # @param value [Boolean, nil] +nil+ means unknown
104
157
  attr_reader :height_accurate
105
158
 
106
- # @return [AIXM::D, nil] margin of error for circular base center point
159
+ # Margin of error for circular base center point.
160
+ #
161
+ # @overload xy_accuracy
162
+ # @return [AIXM::D, nil]
163
+ # @overload xy_accuracy=(value)
164
+ # @param value [AIXM::D, nil]
107
165
  attr_reader :xy_accuracy
108
166
 
109
- # @return [AIXM::D, nil] margin of error for top point
167
+ # Margin of error for top point.
168
+ #
169
+ # @overload z_accuracy
170
+ # @return [AIXM::D, nil]
171
+ # @overload z_accuracy=(value)
172
+ # @param value [AIXM::D, nil]
110
173
  attr_reader :z_accuracy
111
174
 
112
- # @return [Time, Date, String, nil] effective after this point in time
175
+ # Effective after this point in time.
176
+ #
177
+ # @overload valid_from
178
+ # @return [Time, Date, String, nil]
179
+ # @overload valid_from=(value)
180
+ # @param value [Time, Date, String, nil]
113
181
  attr_reader :valid_from
114
182
 
115
- # @return [Time, Date, String, nil] effective until this point in time
183
+ # Effective until this point in time.
184
+ #
185
+ # @overload valid_until
186
+ # @return [Time, Date, String, nil]
187
+ # @overload valid_until=(value)
188
+ # @param value [Time, Date, String, nil]
116
189
  attr_reader :valid_until
117
190
 
118
- # @return [String, nil] free text remarks
119
- attr_reader :remarks
120
-
121
- # @return [Symbol, nil] another obstacle to which a physical link exists
191
+ # Another obstacle to which a physical link exists.
192
+ #
193
+ # @return [AIXM::Feature::Obstacle, nil]
122
194
  attr_reader :linked_to
123
195
 
124
- # @return [Symbol, nil] type of physical link between this and another obstacle
196
+ # Type of physical link between this and another obstacle.
197
+ #
198
+ # @return [Symbol, nil] any of {LINK_TYPES}
125
199
  attr_reader :link_type
126
200
 
201
+ # See the {cheat sheet}[AIXM::Feature::Obstacle] for examples on how to
202
+ # create instances of this class.
127
203
  def initialize(source: nil, region: nil, name: nil, type:, xy:, z:, radius: nil)
128
204
  super(source: source, region: region)
129
205
  self.name, self.type, self.xy, self.z, self.radius = name, type, xy, z, radius
@@ -205,10 +281,6 @@ module AIXM
205
281
  @valid_until = value&.to_time
206
282
  end
207
283
 
208
- def remarks=(value)
209
- @remarks = value&.to_s
210
- end
211
-
212
284
  def linked_to=(value)
213
285
  fail(ArgumentError, "invalid linked to") unless value.is_a?(AIXM::Feature::Obstacle)
214
286
  @linked_to = value
@@ -220,12 +292,16 @@ module AIXM
220
292
  end
221
293
  private :link_type=
222
294
 
223
- # @return [Boolean] whether part of an obstacle group
295
+ # Whether part of an obstacle group.
296
+ #
297
+ # @return [Boolean]
224
298
  def grouped?
225
299
  obstacle_group && obstacle_group.obstacles.count > 1
226
300
  end
227
301
 
228
- # @return [Boolean] whether obstacle is linked to another one
302
+ # Whether obstacle is linked to another one.
303
+ #
304
+ # @return [Boolean]
229
305
  def linked?
230
306
  !!linked_to
231
307
  end
@@ -40,6 +40,7 @@ module AIXM
40
40
  class ObstacleGroup < Feature
41
41
  include AIXM::Association
42
42
  include AIXM::Memoize
43
+ include AIXM::Concerns::Remarks
43
44
 
44
45
  public_class_method :new
45
46
 
@@ -78,9 +79,8 @@ module AIXM
78
79
  end
79
80
  end
80
81
 
81
- # @return [String, nil] free text remarks
82
- attr_reader :remarks
83
-
82
+ # See the {cheat sheet}[AIXM::Feature::ObstacleGroup] for examples on how
83
+ # to create instances of this class.
84
84
  def initialize(source: nil, region: nil, name: nil)
85
85
  super(source: source, region: region)
86
86
  self.name = name
@@ -106,10 +106,6 @@ module AIXM
106
106
  @z_accuracy = value
107
107
  end
108
108
 
109
- def remarks=(value)
110
- @remarks = value&.to_s
111
- end
112
-
113
109
  # @return [String] UID markup
114
110
  def to_uid
115
111
  builder = Builder::XmlMarkup.new(indent: 2)
@@ -20,6 +20,7 @@ module AIXM
20
20
  class Organisation < Feature
21
21
  include AIXM::Association
22
22
  include AIXM::Memoize
23
+ include AIXM::Concerns::Remarks
23
24
 
24
25
  public_class_method :new
25
26
 
@@ -36,29 +37,41 @@ module AIXM
36
37
  }.freeze
37
38
 
38
39
  # @!method members
39
- # @return [Array<AIXM::Feature::Airport,
40
- # AIXM::Feature::Unit,
40
+ # @return [Array<AIXM::Feature::Airport, AIXM::Feature::Unit,
41
41
  # AIXM::Feature::NavigationalAid>] aiports, units or navigational aids
42
42
  #
43
43
  # @!method add_member(member)
44
- # @param member [AIXM::Feature::Airport,
45
- # AIXM::Feature::Unit,
44
+ # @param member [AIXM::Feature::Airport, AIXM::Feature::Unit,
46
45
  # AIXM::Feature::NavigationalAid]
47
46
  # @return [self]
48
47
  has_many :members, accept: [:airport, :unit, 'AIXM::Feature::NavigationalAid']
49
48
 
50
- # @return [String] name of organisation (e.g. "FRANCE")
49
+ # Name of organisation (e.g. "FRANCE")
50
+ #
51
+ # @overload name
52
+ # @return [String]
53
+ # @overload name=(value)
54
+ # @param value [String]
51
55
  attr_reader :name
52
56
 
53
- # @return [Symbol] type of organisation (see {TYPES})
57
+ # Type of organisation
58
+ #
59
+ # @overload type
60
+ # @return [Symbol] any of {TYPES}
61
+ # @overload type=(value)
62
+ # @param value [Symbol] any of {TYPES}
54
63
  attr_reader :type
55
64
 
56
- # @return [String, nil] code of the organisation (e.g. "LF")
65
+ # Code of the organisation (e.g. "LF")
66
+ #
67
+ # @overload id
68
+ # @return [String, nil]
69
+ # @overload id=(value)
70
+ # @param value [String, nil]
57
71
  attr_reader :id
58
72
 
59
- # @return [String, nil] free text remarks
60
- attr_reader :remarks
61
-
73
+ # See the {cheat sheet}[AIXM::Feature::Organisation] for examples on how to
74
+ # create instances of this class.
62
75
  def initialize(source: nil, region: nil, name:, type:)
63
76
  super(source: source, region: region)
64
77
  self.name, self.type = name, type
@@ -83,10 +96,6 @@ module AIXM
83
96
  @id = value&.upcase
84
97
  end
85
98
 
86
- def remarks=(value)
87
- @remarks = value&.to_s
88
- end
89
-
90
99
  # @return [String] UID markup
91
100
  def to_uid
92
101
  builder = Builder::XmlMarkup.new(indent: 2)
@@ -23,6 +23,7 @@ module AIXM
23
23
  class Unit < Feature
24
24
  include AIXM::Association
25
25
  include AIXM::Memoize
26
+ include AIXM::Concerns::Remarks
26
27
 
27
28
  public_class_method :new
28
29
 
@@ -95,15 +96,24 @@ module AIXM
95
96
  # @return [AIXM::Feature::Airport, nil] airport
96
97
  belongs_to :airport
97
98
 
98
- # @return [String] name of unit (e.g. "MARSEILLE ACS")
99
+ # Name of unit (e.g. "MARSEILLE ACS")
100
+ #
101
+ # @overload name
102
+ # @return [String]
103
+ # @overload name=(value)
104
+ # @param value [String]
99
105
  attr_reader :name
100
106
 
101
- # @return [Symbol] type of unit (see {TYPES})
107
+ # Type of unit
108
+ #
109
+ # @overload type
110
+ # @return [Symbol] any of {TYPES}
111
+ # @overload type=(value)
112
+ # @param value [Symbol] any of {TYPES}
102
113
  attr_reader :type
103
114
 
104
- # @return [String, nil] free text remarks
105
- attr_reader :remarks
106
-
115
+ # See the {cheat sheet}[AIXM::Feature::Unit] for examples on how to create
116
+ # instances of this class.
107
117
  def initialize(source: nil, region: nil, organisation:, name:, type:, class:)
108
118
  super(source: source, region: region)
109
119
  self.organisation, self.name, self.type = organisation, name, type
@@ -124,9 +134,15 @@ module AIXM
124
134
  @type = TYPES.lookup(value&.to_s&.to_sym, nil) || fail(ArgumentError, "invalid type")
125
135
  end
126
136
 
127
- # @!attribute class
137
+ # Class of unit.
138
+ #
128
139
  # @note Use +Object#__class__+ alias to query the Ruby object class.
129
- # @return [Symbol] class of unit (see {CLASSES})
140
+ #
141
+ # @!attribute class
142
+ # @overload class
143
+ # @return [Symbol] any of {CLASSES}
144
+ # @overload class=(value)
145
+ # @param value [Symbol] any of {CLASSES}
130
146
  def class
131
147
  @klass
132
148
  end
@@ -135,10 +151,6 @@ module AIXM
135
151
  @klass = CLASSES.lookup(value&.to_s&.to_sym, nil) || fail(ArgumentError, "invalid class")
136
152
  end
137
153
 
138
- def remarks=(value)
139
- @remarks = value&.to_s
140
- end
141
-
142
154
  # @return [String] UID markup
143
155
  def to_uid
144
156
  builder = Builder::XmlMarkup.new(indent: 2)
data/lib/aixm/feature.rb CHANGED
@@ -2,17 +2,31 @@ module AIXM
2
2
 
3
3
  # @abstract
4
4
  class Feature
5
+ include AIXM::Concerns::HashEquality
6
+
5
7
  REGION_RE = /\A[A-Z]{2}\z/.freeze
6
8
 
7
9
  private_class_method :new
8
10
 
9
- # @return [Object] freely usable e.g. to find_by foreign keys
11
+ # Freely usable e.g. to find_by foreign keys.
12
+ #
13
+ # @return [Object]
10
14
  attr_accessor :meta
11
15
 
12
- # @return [String] reference to source of the feature data
16
+ # Reference to source of the feature data.
17
+ #
18
+ # @overload source
19
+ # @return [String]
20
+ # @overload source=(value)
21
+ # @param value [String]
13
22
  attr_reader :source
14
23
 
15
- # @return [String] OFMX region all features in this document belong to
24
+ # OFMX region all features in this document belong to.
25
+ #
26
+ # @overload region
27
+ # @return [String]
28
+ # @overload region=(value)
29
+ # @param value [String]
16
30
  attr_reader :region
17
31
 
18
32
  def initialize(source: nil, region: nil)
@@ -30,10 +44,15 @@ module AIXM
30
44
  @region = value&.upcase
31
45
  end
32
46
 
33
- # @return [Boolean]
47
+ # @see Object#==
34
48
  def ==(other)
35
49
  self.__class__ === other && self.to_uid == other.to_uid
36
50
  end
51
+
52
+ # @see Object#eql?
53
+ def hash
54
+ [self.__class__, to_uid].hash
55
+ end
37
56
  end
38
57
 
39
58
  end
data/lib/aixm/memoize.rb CHANGED
@@ -79,8 +79,8 @@ module AIXM
79
79
  @cache = {}
80
80
  end
81
81
 
82
- def method(method, &)
83
- send(:"call_with#{:out if cached?(method)}_cache", method, &)
82
+ def method(method, &block) # TODO: [ruby-3.1] use anonymous block "&" on this and next line
83
+ send(:"call_with#{:out if cached?(method)}_cache", method, &block)
84
84
  end
85
85
 
86
86
  private
@@ -99,7 +99,7 @@ module AIXM
99
99
  ensure
100
100
  cache.delete(method)
101
101
  end
102
-
103
102
  end
103
+
104
104
  end
105
105
  end
data/lib/aixm/p.rb CHANGED
@@ -7,6 +7,7 @@ module AIXM
7
7
  # @example
8
8
  # AIXM.d(14, :bar)
9
9
  class P
10
+ include AIXM::Concerns::HashEquality
10
11
  include Comparable
11
12
  extend Forwardable
12
13
 
@@ -18,16 +19,29 @@ module AIXM
18
19
  torr: { p: 133.322, mpa: 0.000133322, psi: 0.019336721305636, bar: 0.00133322 }
19
20
  }.freeze
20
21
 
22
+ # Whether pressure is zero.
23
+ #
21
24
  # @!method zero?
22
- # @return [Boolean] whether pressure is zero
25
+ # @return [Boolean]
23
26
  def_delegator :@pres, :zero?
24
27
 
25
- # @return [Float] pressure
28
+ # Pressure
29
+ #
30
+ # @overload pres
31
+ # @return [Float]
32
+ # @overload pres=(value)
33
+ # @param value [Float]
26
34
  attr_reader :pres
27
35
 
28
- # @return [Symbol] unit (see {UNITS})
36
+ # Unit
37
+ #
38
+ # @overload unit
39
+ # @return [Symbol] any of {UNITS}
40
+ # @overload unit=(value)
41
+ # @param value [Symbol] any of {UNITS}
29
42
  attr_reader :unit
30
43
 
44
+ # See the {overview}[AIXM::P] for examples.
31
45
  def initialize(pres, unit)
32
46
  self.pres, self.unit = pres, unit
33
47
  end
@@ -53,13 +67,14 @@ module AIXM
53
67
  fail(ArgumentError, "invalid unit") unless UNITS.has_key? @unit
54
68
  end
55
69
 
70
+ # Convert pressure
71
+ #
56
72
  # @!method to_p
57
73
  # @!method to_mpa
58
74
  # @!method to_psi
59
75
  # @!method to_bar
60
76
  # @!method to_torr
61
- #
62
- # @return [AIXM::P] convert pressure
77
+ # @return [AIXM::P] converted pressure
63
78
  UNITS.each_key do |target_unit|
64
79
  define_method "to_#{target_unit}" do
65
80
  return self if unit == target_unit
@@ -68,22 +83,13 @@ module AIXM
68
83
  end
69
84
 
70
85
  # @see Object#<=>
71
- # @return [Integer]
72
86
  def <=>(other)
73
87
  pres <=> other.send(:"to_#{unit}").pres
74
88
  end
75
89
 
76
90
  # @see Object#==
77
- # @return [Boolean]
78
91
  def ==(other)
79
92
  self.class === other && (self <=> other).zero?
80
93
  end
81
- alias_method :eql?, :==
82
-
83
- # @see Object#hash
84
- # @return [Integer]
85
- def hash
86
- to_s.hash
87
- end
88
94
  end
89
95
  end
@@ -16,7 +16,8 @@ module AIXM
16
16
  class PayloadHash
17
17
  IGNORED_ATTRIBUTES = %w(mid source).freeze
18
18
 
19
- # @param fragment [Nokogiri::XML::DocumentFragment, Nokogiri::XML::Element, String] XML fragment
19
+ # @param fragment [Nokogiri::XML::DocumentFragment, Nokogiri::XML::Element,
20
+ # String] XML fragment
20
21
  def initialize(fragment)
21
22
  @fragment = case fragment
22
23
  when Nokogiri::XML::DocumentFragment then fragment
@@ -25,7 +26,9 @@ module AIXM
25
26
  end
26
27
  end
27
28
 
28
- # @return [String] UUIDv3
29
+ # UUIDv3
30
+ #
31
+ # @return [String]
29
32
  def to_uuid
30
33
  uuid_for payload_array
31
34
  end
data/lib/aixm/r.rb CHANGED
@@ -8,13 +8,25 @@ module AIXM
8
8
  # AIXM.r(AIXM.d(25, :m), AIXM.d(20, :m)) # rectangle
9
9
  # AIXM.r(AIXM.d(25, :m)) # square
10
10
  class R
11
+ include AIXM::Concerns::HashEquality
11
12
 
12
- # @return [AIXM::D] rectangle length
13
+ # Rectangle length
14
+ #
15
+ # @overload length
16
+ # @return [AIXM::D]
17
+ # @overload length=(value)
18
+ # @param value [AIXM::D]
13
19
  attr_reader :length
14
20
 
15
- # @return [AIXM::D] rectangle width
21
+ # Rectangle width
22
+ #
23
+ # @overload width
24
+ # @return [AIXM::D]
25
+ # @overload width=(value)
26
+ # @param value [AIXM::D]
16
27
  attr_reader :width
17
28
 
29
+ # See the {overview}[AIXM::R] for examples.
18
30
  def initialize(length, width=nil)
19
31
  self.length, self.width = length, (width || length)
20
32
  end
@@ -37,7 +49,7 @@ module AIXM
37
49
  end
38
50
  end
39
51
 
40
- # Calculate the surface in square meters
52
+ # Calculate the surface in square meters.
41
53
  #
42
54
  # @return [Float]
43
55
  def surface
@@ -45,18 +57,9 @@ module AIXM
45
57
  end
46
58
 
47
59
  # @see Object#==
48
- # @return [Boolean]
49
60
  def ==(other)
50
61
  self.class === other && length == other.length && width == other.width
51
62
  end
52
- alias_method :eql?, :==
53
-
54
- # @see Object#hash
55
- # @return [Integer]
56
- def hash
57
- to_s.hash
58
- end
59
63
 
60
64
  end
61
-
62
65
  end
@@ -128,8 +128,30 @@ module AIXM
128
128
  # @note This is a refinement for +Object+
129
129
  # @return [Object]
130
130
  refine Object do
131
- def then_if(condition, &)
132
- condition ? self.then(&) : self
131
+ def then_if(condition, &block) # TODO: [ruby-3.1] use anonymous block "&" on this and next line
132
+ condition ? self.then(&block) : self
133
+ end
134
+ end
135
+
136
+ # @!method Range.from
137
+ # Returns a Range covering the given object.
138
+ #
139
+ # To ease coverage tests in mixed arrays of single objects and object
140
+ # ranges, this method assures you're always dealing with objects. It
141
+ # returns self if it is already a Range, otherwise builds one with the
142
+ # given single object as both beginning and end.
143
+ #
144
+ # @example
145
+ # Range.from(5) # => (5..5)
146
+ # Range.from(1..3) # => (1..3)
147
+ #
148
+ # @note This is a refinement for +Range+
149
+ # @param object [Object]
150
+ # @return [Range]
151
+ #refine Range do
152
+ refine Range.singleton_class do
153
+ def from(object)
154
+ object.is_a?(Range) ? object : (object..object)
133
155
  end
134
156
  end
135
157
 
@@ -140,6 +162,7 @@ module AIXM
140
162
  # /^(foo)(?<name>bar)/.decapture # => /^(?:foo)(?:bar)/
141
163
  #
142
164
  # @note This is a refinement for +Regexp+
165
+ # @return [Regexp]
143
166
  refine Regexp do
144
167
  def decapture
145
168
  Regexp.new(to_s.gsub(/\(\?<\w+>|(?<![^\\]\\)\((?!\?)/, '(?:'))
@@ -154,6 +177,7 @@ module AIXM
154
177
  # # => AIXM::Feature::NavigationalAid
155
178
  #
156
179
  # @note This is a refinement for +String+
180
+ # @return [Class]
157
181
  refine String do
158
182
  def to_class
159
183
  Object.const_get(self)
@@ -170,6 +194,7 @@ module AIXM
170
194
  #
171
195
  # @see https://www.rubydoc.info/gems/dry-inflector
172
196
  # @note This is a refinement for +String+
197
+ # @return [String]
173
198
  refine String do
174
199
  def inflect(*inflections)
175
200
  inflections.inject(self) do |memo, inflection|
@@ -178,6 +203,21 @@ module AIXM
178
203
  end
179
204
  end
180
205
 
206
+ # @!method compact
207
+ # Collapse whitespace to one space, but leave +\n+ untouched, then strip
208
+ # what's left.
209
+ #
210
+ # @example
211
+ # " foo\n\nbar baz \r".compact # => "foo\n\nbar baz"
212
+ #
213
+ # @note This is a refinement for +String+
214
+ # @return [String] compacted string
215
+ refine String do
216
+ def compact
217
+ split("\n").map { _1.gsub(/\s+/, ' ') }.join("\n").strip
218
+ end
219
+ end
220
+
181
221
  # @!method indent(number)
182
222
  # Indent every line of a string with +number+ spaces.
183
223
  #