rdoba 0.9.1 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +7 -7
  2. data/.gitignore +4 -0
  3. data/.travis.yml +28 -0
  4. data/CHANGES.md +6 -0
  5. data/Gemfile +5 -0
  6. data/README.md +87 -108
  7. data/Rakefile +62 -54
  8. data/TODO +6 -0
  9. data/features/mixin.feature +85 -0
  10. data/features/step_definitions/mixin_steps.rb +305 -0
  11. data/features/support/env.rb +35 -145
  12. data/features/support/mixin_support.rb +17 -0
  13. data/html/.keep +0 -0
  14. data/lib/rdoba/_version_.rb +3 -1
  15. data/lib/rdoba/a.rb +44 -42
  16. data/lib/rdoba/bcd.rb +43 -26
  17. data/lib/rdoba/blank.rb +14 -0
  18. data/lib/rdoba/combinations.rb +17 -15
  19. data/lib/rdoba/common.rb +53 -68
  20. data/lib/rdoba/debug.rb +9 -3
  21. data/lib/rdoba/deploy.rb +55 -50
  22. data/lib/rdoba/dup.rb +31 -31
  23. data/lib/rdoba/fe.rb +6 -5
  24. data/lib/rdoba/gem.rb +33 -29
  25. data/lib/rdoba/hashorder.rb +24 -24
  26. data/lib/rdoba/io.rb +81 -74
  27. data/lib/rdoba/merge.rb +21 -0
  28. data/lib/rdoba/mixin/time.rb +17 -0
  29. data/lib/rdoba/mixin/try.rb +11 -0
  30. data/lib/rdoba/mixin/try_1_9_0.rb +9 -0
  31. data/lib/rdoba/mixin/wait_if.rb +27 -0
  32. data/lib/rdoba/mixin.rb +373 -52
  33. data/lib/rdoba/numeric.rb +19 -17
  34. data/lib/rdoba/os.rb +127 -0
  35. data/lib/rdoba/re.rb +4 -4
  36. data/lib/rdoba/require.rb +24 -19
  37. data/lib/rdoba/roman.rb +32 -22
  38. data/lib/rdoba/strings.rb +6 -144
  39. data/lib/rdoba/yaml.rb +20 -18
  40. data/lib/rdoba.rb +50 -47
  41. data/rdoba.gemspec +33 -26
  42. data/tddium.yml +11 -0
  43. metadata +184 -77
  44. data/features/bcd.feature +0 -29
  45. data/features/log.feature +0 -206
  46. data/features/step_definitions/bcd_steps.rb +0 -69
  47. data/features/step_definitions/log_steps.rb +0 -164
  48. data/lib/rdoba/log.rb +0 -248
  49. data/test/helper.rb +0 -18
  50. data/test/rdoba_test.rb.stub +0 -59
  51. data/test/test_rdoba.rb +0 -7
data/lib/rdoba/mixin.rb CHANGED
@@ -1,57 +1,378 @@
1
1
  #!/usr/bin/ruby -KU
2
- #encoding:utf-8
2
+ # frozen_string_literal: true
3
+
4
+ class String
5
+ # TODO: obsolete
6
+ ByteByByte = 0
7
+ FirstChar = 1
8
+ end
3
9
 
4
10
  module Rdoba
5
- module Mixin
6
- module To_hArray
7
- def to_h options = {}
8
- h = {}
9
- self.each do |v|
10
- if v.is_a? Array
11
- if h.key? v[ 0 ]
12
- if !h[ v[ 0 ] ].is_a? Array
13
- h[ v[ 0 ] ] = [ h[ v[ 0 ] ] ] ; end
14
-
15
- if v.size > 2
16
- h[ v [ 0 ] ].concat v[ 1..-1 ]
17
- else
18
- h[ v [ 0 ] ] << v[ 1 ] ; end
19
- else
20
- h[ v[ 0 ] ] = v.size > 2 && v[ 1..-1] || v[ 1 ] ; end
21
- else
22
- if h.key? v
23
- if !h[ v ].is_a? Array
24
- h[ v ] = [ h[ v ] ] ; end
25
-
26
- h[ v ] << v
27
- else
28
- h[ v ] = nil ; end ; end ; end
29
-
30
- if options[ :save_unique ]
31
- h.each_pair do |k,v|
32
- if v.is_a? Array
33
- v.uniq! ; end ; end ; end
34
-
35
- h ; end ; end
36
-
37
- module EmptyObject
38
- def empty?
39
- false ; end ; end
40
-
41
- module EmptyNilClass
42
- def empty?
43
- true ; end ; end ; end
44
-
45
- def self.mixin options
46
- ( options || [] ).each do |value|
47
- case value
48
- when :to_h
49
- Array.send :include, Rdoba::Mixin::To_hArray
50
- when :empty
51
- Object.send :include, Rdoba::Mixin::EmptyObject
52
- NilClass.send :include, Rdoba::Mixin::EmptyNilClass
53
- else
54
- Kernel.puts STDERR, "Invalid rdoba-mixin options key: #{value.to_s}"
55
- end ; end ; end ; end
11
+ module Mixin
12
+ class InvalidOption < StandardError
13
+ end
14
+
15
+ module CompareString
16
+ def compare_to(value, opts = {})
17
+ if opts == :ignore_diacritics || opts.instance_of?(Hash) && opts.key?(:ignore_diacritics)
18
+ # TODO: verify composite range
19
+ def crop_diacritics(x)
20
+ (x < 0x300 || x > 0x36f && x < 0x483 || x > 0x487 && x < 0xa67c || x > 0xa67d) && x || nil
21
+ end
22
+
23
+ (unpack('U*').map do |x| crop_diacritics(x)end.compact) <=>
24
+ (value.unpack('U*').map do |x| crop_diacritics(x)end.compact)
25
+ else
26
+ self <=> value
27
+ end
28
+ end
29
+ end
30
+
31
+ module ReverseString
32
+ Fixups = [:reverse]
33
+
34
+ Aliases = { __rdoba_mixin_reverse_orig__: :reverse }
35
+
36
+ def __rdoba_mixin_reverse__(step = 1)
37
+ if (!step.is_a?(Numeric) || step < 0) && step != :byte_by_byte
38
+ raise "Invalid step value #{step.inspect}"
39
+ end
40
+
41
+ if [:byte_by_byte, String::ByteByByte].include?(step)
42
+ arr = []
43
+ each_byte do |byte|
44
+ arr << byte.chr
45
+ end
46
+ arr.reverse.join.force_encoding(encoding)
47
+ elsif step == 1
48
+ __rdoba_mixin_reverse_orig__
49
+ elsif step > 1
50
+ res = ''
51
+ offset = (size + 1) / step * step - step
52
+ (0..offset).step(step) do |shift|
53
+ res += self[offset - shift..offset - shift + 1]
54
+ end
55
+ res
56
+ end
57
+ end
58
+ end
59
+
60
+ module CaseString
61
+ Fixups = %i[upcase downcase]
62
+
63
+ Aliases = { __rdoba_mixin_upcase_orig__: :upcase, __rdoba_mixin_downcase_orig__: :downcase }
64
+
65
+ ConvertTable = {
66
+ up: {
67
+ ranges: [
68
+ { ords: [(0xE0..0xFF), (0x3B1..0x3CB), (0x430..0x44F)], change: proc { |chr, _value| chr -= 0x20 } },
69
+ { ords: [(0x3AC..0x3AC)], change: proc { |ord| ord -= 0x26 } },
70
+ { ords: [(0x3AD..0x3AF)], change: proc { |ord| ord -= 0x25 } },
71
+ { ords: [(0x3B0..0x3B0)], change: proc { |ord| ord -= 0x22 } },
72
+ {
73
+ ords: [
74
+ (0x1F00..0x1F07),
75
+ (0x1F10..0x1F17),
76
+ (0x1F20..0x1F27),
77
+ (0x1F30..0x1F37),
78
+ (0x1F40..0x1F47),
79
+ (0x1F50..0x1F57),
80
+ (0x1F60..0x1F67),
81
+ (0x1F80..0x1F87),
82
+ (0x1F90..0x1F97),
83
+ (0x1Fa0..0x1Fa7),
84
+ (0x1Fb0..0x1Fb3)
85
+ ],
86
+ change: proc { |ord| ord += 0x8 }
87
+ },
88
+ { ords: [(0x450..0x45F)], change: proc { |ord| ord -= 0x50 } },
89
+ {
90
+ ords: [
91
+ (0x100..0x1B9),
92
+ (0x1C4..0x233),
93
+ (0x460..0x481),
94
+ (0x48A..0x523),
95
+ (0x1E00..0x1E95),
96
+ (0x1EA0..0x1EFF),
97
+ (0x0A642..0xA667),
98
+ (0x0A680..0x0A697),
99
+ (0xA722..0xA7A9)
100
+ ],
101
+ change: proc { |ord| ord.odd? && (ord - 1) || ord }
102
+ }
103
+ ],
104
+ default:
105
+ proc do |ord|
106
+ [ord].pack('U').__rdoba_mixin_upcase_orig__
107
+ end
108
+ },
109
+ down: {
110
+ ranges: [
111
+ { ords: [(0xC0..0xDF), (0x391..0x3AB), (0x410..0x42F)], change: proc { |chr, _value| chr += 0x20 } },
112
+ { ords: [(0x386..0x386)], change: proc { |ord| ord += 0x26 } },
113
+ { ords: [(0x388..0x38A)], change: proc { |ord| ord += 0x25 } },
114
+ { ords: [(0x38E..0x38E)], change: proc { |ord| ord += 0x22 } },
115
+ {
116
+ ords: [
117
+ (0x1F08..0x1F0F),
118
+ (0x1F18..0x1F1F),
119
+ (0x1F28..0x1F2F),
120
+ (0x1F38..0x1F3F),
121
+ (0x1F48..0x1F4F),
122
+ (0x1F58..0x1F5F),
123
+ (0x1F68..0x1F6F),
124
+ (0x1F88..0x1F8F),
125
+ (0x1F98..0x1F9F),
126
+ (0x1Fa8..0x1FaF),
127
+ (0x1Fb8..0x1FbA)
128
+ ],
129
+ change: proc { |ord| ord -= 0x8 }
130
+ },
131
+ { ords: [(0x400..0x40F)], change: proc { |ord| ord += 0x50 } },
132
+ {
133
+ ords: [
134
+ (0x100..0x1B9),
135
+ (0x1C4..0x233),
136
+ (0x450..0x481),
137
+ (0x48A..0x523),
138
+ (0x1E00..0x1E95),
139
+ (0x1EA0..0x1EFF),
140
+ (0x0A642..0xA667),
141
+ (0x0A680..0x0A697),
142
+ (0xA722..0xA7A9)
143
+ ],
144
+ change: proc { |ord| ord.even? && (ord + 1) || ord }
145
+ }
146
+ ],
147
+ default:
148
+ proc do |ord|
149
+ [ord].pack('U').__rdoba_mixin_downcase_orig__
150
+ end
151
+ }
152
+ }
153
+
154
+ def self.change_case_char(dest, char)
155
+ ord = char.is_a?(String) ? char.ord : char.to_i
156
+ table = ConvertTable[dest]
157
+ nord =
158
+ table[:ranges].each do |range|
159
+ c =
160
+ range[:ords].each do |r|
161
+ if r.include?(ord)
162
+ break false
163
+ end
164
+ end
165
+ unless c
166
+ break range[:change].call ord
167
+ end
168
+ end
169
+
170
+ unless nord.is_a? Numeric
171
+ return table[:default].call ord
172
+ end
173
+
174
+ [nord].pack('U')
175
+ end
176
+
177
+ def self.up_char(char)
178
+ CaseString.change_case_char :up, char
179
+ end
180
+
181
+ def self.downcase_char(char)
182
+ CaseString.change_case_char :down, char
183
+ end
184
+
185
+ if RUBY_VERSION < '1.9'
186
+ alias setbyte []=
187
+
188
+ def encoding
189
+ 'UTF-8'
190
+ end
56
191
 
192
+ def force_encoding(*_args)
193
+ self
194
+ end
57
195
 
196
+ def ord
197
+ a = nil
198
+ each_byte do |b|
199
+ case (b & 0xC0)
200
+ when 0xc0
201
+ a = (b & 0x3F)
202
+ when 0x80
203
+ return (a << 6) + (b & 0x3F)
204
+ else
205
+ return b
206
+ end
207
+ end
208
+ end
209
+ end
210
+
211
+ def __rdoba_mixin_downcase__(options = {})
212
+ __rdoba_mixin_changecase__ :down, options
213
+ end
214
+
215
+ def __rdoba_mixin_upcase__(options = {})
216
+ __rdoba_mixin_changecase__ :up, options
217
+ end
218
+
219
+ def __rdoba_mixin_changecase__(reg, options = {})
220
+ unless %i[up down].include? reg
221
+ return self
222
+ end
223
+
224
+ re = Regexp.new '[\x80-\xFF]', nil, 'n'
225
+ if options == String::FirstChar || options.include?(:first_char)
226
+ r = dup
227
+ r[0] = CaseString.change_case_char reg, ord
228
+ r
229
+ elsif dup.force_encoding('ASCII-8BIT').match re
230
+ unpack('U*').map do |chr|
231
+ CaseString.change_case_char reg, chr
232
+ end.join
233
+ elsif reg == :up
234
+ __rdoba_mixin_upcase_orig__
235
+ else
236
+ __rdoba_mixin_downcase_orig__
237
+ end
238
+ end
239
+ end
240
+
241
+ module To_hArray
242
+ def to_h(options = {})
243
+ h = {}
244
+ each do |v|
245
+ if v.is_a? Array
246
+ if h.key? v[0]
247
+ unless h[v[0]].is_a? Array
248
+ h[v[0]] = [h[v[0]]]
249
+ end
250
+
251
+ if v.size > 2
252
+ h[v[0]].concat v[1..-1]
253
+ else
254
+ h[v[0]] << v[1]
255
+ end
256
+ else
257
+ h[v[0]] = v.size > 2 && v[1..-1] || v[1]
258
+ end
259
+ elsif h.key? v
260
+ unless h[v].is_a? Array
261
+ h[v] = [h[v]]
262
+ end
263
+
264
+ h[v] << v
265
+ else
266
+ h[v] = nil
267
+ end
268
+ end
269
+
270
+ if options[:save_unique]
271
+ h.each_pair do |_k, v|
272
+ if v.is_a? Array
273
+ v.uniq!
274
+ end
275
+ end
276
+ end
277
+
278
+ h
279
+ end
280
+ end
281
+
282
+ module Split_byArray
283
+ #
284
+ # +split_by+ method splits the +self+ array by a condition,
285
+ # which is evaliated in a passed block, in two versions that are
286
+ # the return value. Usage:
287
+ #
288
+ # require 'rdoba'
289
+ #
290
+ # rdoba mixin: :split_by
291
+ #
292
+ # (first, second) = [0,1,2,3].split_by { |value| value % 2 == 0 }
293
+ # first # => [0,2]
294
+ # second # => [1,3]
295
+ #
296
+ def split_by
297
+ idxs = []
298
+ rejected = reject.with_index do |v, i| yield(v) && (idxs << i)end
299
+ [values_at(*idxs), rejected]
300
+ end
301
+ end
302
+
303
+ module EmptyObject
304
+ def empty?
305
+ false
306
+ end
307
+ end
308
+
309
+ module EmptyNilClass
310
+ def empty?
311
+ true
312
+ end
313
+ end
314
+ end
315
+ end
316
+
317
+ if RUBY_VERSION >= '2.0.0'
318
+ require_relative 'mixin/try'
319
+ else
320
+ require_relative 'mixin/try_1_9_0'
321
+ end
322
+
323
+ require_relative 'mixin/wait_if'
324
+
325
+ module Rdoba
326
+ def self.mixin(options)
327
+ [options[:value]].flatten.each do |value|
328
+ case value
329
+ when :case
330
+ Mixin::CaseString::Aliases.each do |k, v|
331
+ ::String.send :alias_method, k, v
332
+ end
333
+ Mixin::CaseString::Fixups.each do |e|
334
+ ::String.class_eval "def #{e}(*args);self.__rdoba_mixin_#{e}__(*args);end", __FILE__, __LINE__
335
+ end
336
+ ::String.include Mixin::CaseString
337
+ when :reverse
338
+ Mixin::ReverseString::Aliases.each do |k, v|
339
+ ::String.send :alias_method, k, v
340
+ end
341
+ Mixin::ReverseString::Fixups.each do |e|
342
+ ::String.class_eval "def #{e}(*args);self.__rdoba_mixin_#{e}__(*args);end", __FILE__, __LINE__
343
+ end
344
+ String.include Mixin::ReverseString
345
+ when :compare
346
+ String.include Mixin::CompareString
347
+ when :to_h
348
+ if [].respond_to?(:to_h)
349
+ m = Mixin::To_hArray.instance_method(:to_h)
350
+ Array.send(:define_method, :to_h, m)
351
+ else
352
+ Array.include Mixin::To_hArray
353
+ end
354
+ when :time
355
+ require_relative 'mixin/time'
356
+ if File.respond_to?(:mtime)
357
+ %i[mtime atime ctime].each do |name|
358
+ m = Mixin::Time.instance_method(name)
359
+ ::File.send(:define_singleton_method, name, m)
360
+ end
361
+ else
362
+ ::File.extend Mixin::Time
363
+ end
364
+ when :wait_if
365
+ Object.include Mixin::Wait_ifKernel
366
+ when :split_by
367
+ Array.include Mixin::Split_byArray
368
+ when :try
369
+ Object.include Mixin::TryObject
370
+ when :empty
371
+ Object.include Mixin::EmptyObject
372
+ NilClass.include Mixin::EmptyNilClass
373
+ else
374
+ raise(Mixin::InvalidOption, 'Invalid rdoba-mixin options key: ' + value.to_s)
375
+ end
376
+ end
377
+ end
378
+ end
data/lib/rdoba/numeric.rb CHANGED
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/ruby -KU
2
- #coding:utf-8
2
+ # frozen_string_literal: true
3
3
 
4
4
  require 'rdoba/common'
5
5
  require 'rdoba/strings'
6
6
 
7
7
  class String
8
- alias :_rdoba_to_i :to_i
8
+ alias _rdoba_to_i to_i
9
9
  def to_i(base = 10, *opts)
10
10
  v = parse_opts(opts)
11
11
  if v[:be]
12
- (str, sign, num) = (self.match /\s*(-?)([0-9a-fx]+)/u).to_a
12
+ str, sign, num = (match /\s*(-?)([0-9a-fx]+)/u).to_a
13
13
  if str
14
- n = num.reverse._rdoba_to_i(base)
15
- sign.empty? && n || -n
14
+ n = num.reverse._rdoba_to_i(base)
15
+ sign.empty? && n || -n
16
16
  else
17
- 0
17
+ 0
18
18
  end
19
19
  else
20
20
  _rdoba_to_i(base)
@@ -22,8 +22,8 @@ class String
22
22
  end
23
23
  end
24
24
 
25
- class Fixnum
26
- alias :_rdoba_to_s :to_s
25
+ class Integer
26
+ alias _rdoba_to_s to_s
27
27
  def to_s(base = 10, *opts)
28
28
  v = parse_opts(opts)
29
29
 
@@ -31,8 +31,10 @@ class Fixnum
31
31
 
32
32
  raise "Base of number can't be equal or less then zero" if base <= 0
33
33
  raise "Padding count numberr can't be equal or less then zero" if v[:padding] <= 0
34
+
34
35
  value = self
35
- minus = if value < 0
36
+ minus =
37
+ if value < 0
36
38
  value = -value
37
39
  true
38
40
  end
@@ -42,7 +44,7 @@ class Fixnum
42
44
  rem += 0x40 - 0x39 if rem >= 10
43
45
  res += (0x30 + rem).chr
44
46
  end
45
- res += "0" * (v[:padding].to_i - res.size) if res.size < v[:padding].to_i
47
+ res += '0' * (v[:padding].to_i - res.size) if res.size < v[:padding].to_i
46
48
  res += 'x0' if v[:style_formatting] and base == 16
47
49
  res += '-' if minus
48
50
  res.reverse
@@ -54,7 +56,8 @@ class Numeric
54
56
  v = parse_opts(opts)
55
57
 
56
58
  value = self
57
- minus = if value < 0
59
+ minus =
60
+ if value < 0
58
61
  value = -value
59
62
  true
60
63
  end
@@ -64,12 +67,14 @@ class Numeric
64
67
  res += rem.chr
65
68
  end
66
69
 
67
- pad_char = if minus
70
+ pad_char =
71
+ if minus
68
72
  negres += ''
69
73
  over = 1
70
74
  res.each_byte do |byte|
71
75
  negbyte = 255 - byte + over
72
- negres += if negbyte > 255
76
+ negres +=
77
+ if negbyte > 255
73
78
  over = 1
74
79
  0
75
80
  else
@@ -85,9 +90,6 @@ class Numeric
85
90
 
86
91
  res += pad_char * (v[:padding].to_i - res.size) if res.size < v[:padding].to_i
87
92
 
88
- plain = (v[:be] ? res.reverse(String::ByteByByte) : res).to_p
89
- plain
93
+ (v[:be] ? res.reverse(String::ByteByByte) : res).to_p
90
94
  end
91
95
  end
92
-
93
-
data/lib/rdoba/os.rb ADDED
@@ -0,0 +1,127 @@
1
+ require 'ostruct'
2
+
3
+ require 'rdoba/blank'
4
+
5
+ class Object
6
+ def to_os
7
+ OpenStruct.new(self.to_h.map {|(x, y)| [x.to_s, [Hash, Array].include?(y.class) && y.to_os || y] }.to_h)
8
+ end
9
+ end
10
+
11
+ class Array
12
+ def to_os
13
+ OpenStruct.new(self.map.with_index {|y, x| [x.to_s, [Hash, Array].include?(y.class) && y.to_os || y] }.to_h)
14
+ end
15
+ end
16
+
17
+ class Integer
18
+ def to_sym
19
+ to_s.to_sym
20
+ end
21
+ end
22
+
23
+ class OpenStruct
24
+ def merge_to other
25
+ OpenStruct.new(other.to_h.merge(self.to_h))
26
+ end
27
+
28
+ def merge other
29
+ OpenStruct.new(self.to_h.merge(other.to_h))
30
+ end
31
+
32
+ def map *args, &block
33
+ res = self.class.new
34
+
35
+ self.each_pair do |key, value|
36
+ res[key] = block[key, value]
37
+ end
38
+
39
+ res
40
+ end
41
+
42
+ def select &block
43
+ res = self.class.new
44
+
45
+ self.each_pair do |key, value|
46
+ res[key] = value if block[key, value]
47
+ end
48
+
49
+ res
50
+ end
51
+
52
+ def compact
53
+ select { |_, value| !value.blank? }
54
+ end
55
+
56
+ def each *args, &block
57
+ self.each_pair(*args, &block)
58
+ end
59
+
60
+ def reduce default = nil, &block
61
+ res = default
62
+
63
+ self.each_pair do |key, value|
64
+ res = block[res, key, value]
65
+ end
66
+
67
+ res
68
+ end
69
+
70
+ # +deep_merge+ deeply merges the Open Struct hash structure with the +other_in+ enumerating it key by key.
71
+ # +options+ are the options to change behaviour of the method. It allows two keys: :mode, and :dedup
72
+ # :mode key can be :append, :prepend, or :replace, defaulting to :append, when mode is to append, it combines duplicated
73
+ # keys' values into an array, when :prepend it prepends an other value before previously stored one unlike for :append mode,
74
+ # when :replace it replace duplicate values with a last ones.
75
+ # :dedup key can be true, or false. It allows to deduplicate values when appending or prepending values.
76
+ # Examples:
77
+ # open_struct.deep_merge(other_open_struct)
78
+ # open_struct.deep_merge(other_open_struct, :prepend)
79
+ #
80
+ def deep_merge other_in, options_in = {}
81
+ return self if other_in.nil? or other_in.blank?
82
+
83
+ options = { mode: :append }.merge(options_in)
84
+
85
+ other =
86
+ if other_in.is_a?(OpenStruct)
87
+ other_in.dup
88
+ elsif other_in.is_a?(Hash)
89
+ other_in.to_os
90
+ else
91
+ OpenStruct.new(nil => other_in)
92
+ end
93
+
94
+ self.reduce(other) do |res, key, value|
95
+ res[key] =
96
+ if res.table.keys.include?(key)
97
+ case value
98
+ when Hash, OpenStruct
99
+ value.deep_merge(res[key], options)
100
+ when Array
101
+ value.concat([res[key]].compact.flatten(1))
102
+ when NilClass
103
+ res[key]
104
+ else
105
+ value_out =
106
+ if options[:mode] == :append
107
+ [res[key], value].compact.flatten(1)
108
+ elsif options[:mode] == :prepend
109
+ [value, res[key]].compact.flatten(1)
110
+ else
111
+ value
112
+ end
113
+
114
+ if value_out.is_a?(Array) && options[:dedup]
115
+ value_out.uniq
116
+ else
117
+ value_out
118
+ end
119
+ end
120
+ else
121
+ value
122
+ end
123
+
124
+ res
125
+ end
126
+ end
127
+ end
data/lib/rdoba/re.rb CHANGED
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/ruby -KU
2
- #coding:utf-8
2
+ # frozen_string_literal: true
3
3
 
4
4
  class String
5
5
  def to_res
6
- ostr = self.dup
6
+ ostr = dup
7
7
  res = ''
8
8
  while true
9
- m = ostr.match(/(?:([+\[\]\\().*?{}^$\/|])|«([^«]*)»)/u)
9
+ m = ostr.match(%r{(?:([+\[\]\\().*?{}^$/|])|«([^«]*)»)}u)
10
10
  break unless m
11
+
11
12
  res += m.pre_match + (m[2] || m[1] && ('\\' + m[1]))
12
13
  ostr = m.post_match
13
14
  end
@@ -19,4 +20,3 @@ class String
19
20
  /#{to_res}/ui
20
21
  end
21
22
  end
22
-