rdoba 0.9.1 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
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
-