Module: AIXM::Refinements

Defined in:
lib/aixm/refinements.rb

Constant Summary collapse

UPTRANS_FILTER =
%r(
  [^A-Z0-9, !"&#$%'\(\)\*\+\-\./:;<=>\[email protected]\[\\\]\^_\|\{\}]
)x.freeze
UPTRANS_MAP =
{
  'Ä' => 'AE',
  'Ö' => 'OE',
  'Ü' => 'UE',
  'Æ' => 'AE',
  'Œ' => 'OE',
  "Å" => "Aa",
  "Ø" => "Oe"
}.freeze

Instance Method Summary collapse

Instance Method Details

#decaptureObject

Note:

This is a refinement for Regexp

Replace all groups with non-caputuring groups

Examples:

/^(foo)(?<name>bar)/.decapture   # => /^(?:foo)(?:bar)/

143
144
145
146
147
# File 'lib/aixm/refinements.rb', line 143

refine Regexp do
  def decapture
    Regexp.new(to_s.gsub(/\(\?<\w+>|(?<![^\\]\\)\((?!\?)/, '(?:'))
  end
end

#indent(number) ⇒ String

Note:

This is a refinement for String

Indent every line of a string with number spaces.

Examples:

"foo\nbar".indent(2)
# => "  foo\n  bar"

191
192
193
194
195
196
# File 'lib/aixm/refinements.rb', line 191

refine String do
  def indent(number)
    whitespace = ' ' * number
    gsub(/^/, whitespace)
  end
end

#inflectObject

Note:

This is a refinement for String

Apply inflections from the dry-inflector gem

Examples:

s = "AIXM::Feature::NavigationalAid"
s.inflect(:demodulize, :tableize, :pluralize)
# => "navigational_aids"

See Also:


173
174
175
176
177
178
179
# File 'lib/aixm/refinements.rb', line 173

refine String do
  def inflect(*inflections)
    inflections.inject(self) do |memo, inflection|
      AIXM.config.inflector.send(inflection, memo)
    end
  end
end

#lookup(key_or_value, fallback = omitted=true) ⇒ Object

Note:

This is a refinement for Hash

Fetch a value from the hash, but unlike Hash#fetch, if key_or_value is no hash key, check whether key_or_value is a hash value and if so return it.

Examples:

h = { one: 1, two: 2, three: 3, four: :three }
h.lookup(:one)              # => 1
h.lookup(1)                 # => 1
h.lookup(:three)            # => 3 (key has priority over value)
h.lookup(:foo)              # => KeyError
h.lookup(:foo, :fallback)   # => :fallback
h.lookup(:foo, nil)         # => nil

Raises:

  • (KeyError)

    if neither a matching hash key nor hash value are found and no fallback value has been passed


113
114
115
116
117
118
119
# File 'lib/aixm/refinements.rb', line 113

refine Hash do
  def lookup(key_or_value, fallback=omitted=true)
    self[key_or_value] ||
      (key_or_value if has_value?(key_or_value)) ||
      (omitted ? fail(KeyError, "key or value `#{key_or_value}' not found") : fallback)
  end
end

#then_ifObject

Note:

This is a refinement for Object

Same as Object#then but only applied if the condition is true.

Examples:

"foobar".then_if(false) { _1.gsub(/o/, 'i') }   # => "foobar"
"foobar".then_if(true) { _1.gsub(/o/, 'i') }    # => "fiibar"

130
131
132
133
134
# File 'lib/aixm/refinements.rb', line 130

refine Object do
  def then_if(condition, &block)
    condition ? self.then(&block) : self
  end
end

#to_classObject

Note:

This is a refinement for String

Convert string to class

Examples:

"AIXM::Feature::NavigationalAid".to_class
# => AIXM::Feature::NavigationalAid

157
158
159
160
161
# File 'lib/aixm/refinements.rb', line 157

refine String do
  def to_class
    Object.const_get(self)
  end
end

#to_ddFloat

Note:

This is a refinement for String

Convert DMS angle to DD or nil if the notation is not recognized.

Supported notations:

  • {-}{DD}D°MM'SS{.SS}“{[NESW]}

  • {-}{DD}D MM SS{.SS} {[NESW]}

  • -}{DD}DMMSS{.SS

Quite a number of typos are tolerated such as the wrong use of minute ' and second markers as well as the use of decimal comma , instead of dot ..

Examples:

%q(43°12'77.92").to_dd
# => 43.22164444444445
"431277.92S".to_dd
# => -43.22164444444445
%q(-123).to_dd
# => nil

220
221
222
223
224
225
226
227
228
229
230
# File 'lib/aixm/refinements.rb', line 220

refine String do
  def to_dd
    if match = self.match(DMS_RE)
      "#{match['sgn']}1".to_i * "#{:- if match['hem_sw']}1".to_i * (
        match['deg'].to_f +
        match['min'].to_f/60 +
        match['sec'].tr(',', '.').to_f/3600
      )
    end
  end
end

#to_digestString

Note:

This is a refinement for Array

Builds a 4 byte hex digest from the Array payload.

Examples:

['foo', :bar, nil, [123]].to_digest
# => "f3920098"

27
28
29
30
31
# File 'lib/aixm/refinements.rb', line 27

refine Array do
  def to_digest
    ::Digest::SHA512.hexdigest(flatten.map(&:to_s).join('|'))[0, 8]
  end
end

#to_dms(padding = 3) ⇒ String

Note:

This is a refinement for Float

Convert DD angle to DMS with the degrees zero padded to padding length.

Examples:

43.22164444444445.to_dms(2)
# => "43°12'77.92\""
43.22164444444445.to_dms
# => "043°12'77.92\""

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/aixm/refinements.rb', line 46

refine Float do
  def to_dms(padding=3)
    degrees = self.abs.floor
    minutes = ((self.abs - degrees) * 60).floor
    seconds = (self.abs - degrees - minutes.to_f / 60) * 3600
    minutes, seconds = minutes + 1, 0 if seconds.round(2) == 60
    degrees, minutes = degrees + 1, 0 if minutes == 60
    %Q(%s%0#{padding}d°%02d'%05.2f") % [
      ('-' if self.negative?),
      self.abs.truncate,
      minutes.abs.truncate,
      seconds.abs
    ]
  end
end

#to_radFloat

Note:

This is a refinement for Float

Convert an angle from degree to radian.

Examples:

45.to_rad
# => 0.7853981633974483

71
72
73
74
75
# File 'lib/aixm/refinements.rb', line 71

refine Float do
  def to_rad
    self * Math::PI / 180
  end
end

#to_timeTime

Note:

This is a refinement for String

Parse string to date and time.

Examples:

'2018-01-01 15:00'.to_time
# => 2018-01-01 15:00:00 +0100

241
242
243
244
245
# File 'lib/aixm/refinements.rb', line 241

refine String do
  def to_time
    Time.parse(self)
  end
end

#trimInteger, Float

Note:

This is a refinement for Float

Convert whole numbers to Integer and leave all other untouched.

Examples:

3.0.trim
# => 3
3.3.trim
# => 3.3

88
89
90
91
92
# File 'lib/aixm/refinements.rb', line 88

refine Float do
  def trim
    (self % 1).zero? ? self.to_i : self
  end
end

#uptransString

Note:

This is a refinement for String

Upcase and transliterate to match the reduced character set for AIXM names and titles.

See UPTRANS_MAP for supported diacryts and UPTRANS_FILTER for the list of allowed characters in the returned value.

Examples:

"Nîmes-Alès".uptrans
# => "NIMES-ALES"
"Zürich".uptrans
# => "ZUERICH"

262
263
264
265
266
267
268
269
270
271
# File 'lib/aixm/refinements.rb', line 262

refine String do
  def uptrans
    self.dup.tap do |string|
      string.upcase!
      string.gsub!(/(#{UPTRANS_MAP.keys.join('|')})/, UPTRANS_MAP)
      string.unicode_normalize!(:nfd)
      string.gsub!(UPTRANS_FILTER, '')
    end
  end
end