thefox-ext 1.9.0 → 2.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 569a588809c70468e59dc2d762bf261d94108cc4d9c535c664c518c99b820914
4
- data.tar.gz: 9307e0cf0b76da29e09537bc93e7e77f70137dcb69621d94089ad24f08a080d2
3
+ metadata.gz: da29c60568cd97ae87c97b6d299215f77c4ab55ad711bbae6793d762b441fcce
4
+ data.tar.gz: 1a31f430986f74719a80e3900152acfb7b714f553a1b26204dc6b615f2f7455e
5
5
  SHA512:
6
- metadata.gz: 4e8c14d434bd57584ae5f72d2c99923af6da39c0e88b1e2cee8afb5f03776d1997be3a994e54f97632c9b96e7f280a4e2249717cdb1d4ee1163f9be7c8c98e20
7
- data.tar.gz: 5f4527fb0be38f6e1c4018a8896374475405565907484d894e5294bdb43f989050f1af2217b25c12095d454a64f162fd148355a0685218560d6ad1e085e6c735
6
+ metadata.gz: 7f014e0cfd460e98cec083744b72a40bdd73d4b2558ce921c7ac003b0aad7eadd9f73deafc1a8bff5392206eabb51b9f8442b8f034c512227b4afc7ad94622bc
7
+ data.tar.gz: f559019dcc8cb52656b785b71db0fd91cfc786b7246b22c4b533a7b5584317ac9114f0b32c0de38c1a2ce277fe7ff8ec231fdbebb1e436b3c602d7775644957d
@@ -10,6 +10,7 @@ on:
10
10
  push:
11
11
  branches:
12
12
  - master
13
+ - feature/*
13
14
 
14
15
  jobs:
15
16
  test:
@@ -17,7 +18,6 @@ jobs:
17
18
  strategy:
18
19
  matrix:
19
20
  ruby-version:
20
- - '2.3'
21
21
  - '2.4'
22
22
  - '2.5'
23
23
  - '2.6'
data/CHANGELOG-v1.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Release Notes for Extended Ruby Classes v1.x
2
2
 
3
+ ## v1.10.0
4
+
5
+ - [DEPRECATION] `Array.resolve_range_str` is deprecated.
6
+ - [DEPRECATION] `String.resolve_range` is deprecated.
7
+
3
8
  ## v1.9.0
4
9
 
5
10
  - Tests
data/CHANGELOG-v2.md ADDED
@@ -0,0 +1,8 @@
1
+ # Release Notes for Extended Ruby Classes v2.x
2
+
3
+ ## v2.0.0
4
+
5
+ - Removed deprecated `Array.resolve_range_str`.
6
+ - Removed deprecated `String.resolve_range`.
7
+ - Drop Ruby version 2.3 support.
8
+ - Added Range Resolver class.
data/README.md CHANGED
@@ -21,7 +21,7 @@ gem install thefox-ext
21
21
  or via `Gemfile`:
22
22
 
23
23
  ```ruby
24
- gem 'thefox-ext', '~>1.9'
24
+ gem 'thefox-ext', '~>2.0'
25
25
  ```
26
26
 
27
27
  Use it in your sources:
@@ -40,10 +40,9 @@ require 'thefox-ext'
40
40
  - Date
41
41
  - `today?`
42
42
  - Get week array for a specific date.
43
- - Array
44
- - Range String Resolver
45
43
  - Hash
46
44
  - Recursive Merge
45
+ - Range String Resolver
47
46
 
48
47
  ## Project Links
49
48
 
data/bin/dev CHANGED
@@ -4,10 +4,7 @@
4
4
  require 'thefox-ext'
5
5
  require 'pp'
6
6
 
7
- # pp '5{1,2}'.resolve_range()
8
- # pp '1,2{1-3,5,6,7},4,5{1,2}'.resolve_range()
9
- # pp [1, 2].resolve_range_str('3, 4')
10
- # pp Array.resolve_range_str('3,4')
11
- # pp '3, 4'.resolve_range()
12
- # pp '3, 4'.resolve_range()
13
- # pp '3, 4'.resolve_range2()
7
+ s = '99-110/4'
8
+ s = '99-110/*'
9
+ rr = TheFox::Range::Resolver.new(s)
10
+ pp rr.to_a
data/bin/test.sh CHANGED
@@ -10,4 +10,5 @@ which bundler &> /dev/null || { echo 'ERROR: bundler not found in PATH'; exit 1;
10
10
 
11
11
  cd "${SCRIPT_BASEDIR}/.."
12
12
 
13
+ echo 'run tests'
13
14
  bundler exec ./test/suite_all.rb $*
data/lib/thefox-ext.rb CHANGED
@@ -8,6 +8,18 @@ require 'thefox-ext/ext/integer'
8
8
  require 'thefox-ext/ext/nil'
9
9
  require 'thefox-ext/ext/string'
10
10
  require 'thefox-ext/ext/true'
11
- require 'thefox-ext/ext/array'
12
11
 
13
12
  require 'thefox-ext/console'
13
+ require 'thefox-ext/range/resolver'
14
+ require 'thefox-ext/range/lexer/lexer'
15
+ require 'thefox-ext/range/lexer/base'
16
+ require 'thefox-ext/range/lexer/scope'
17
+ require 'thefox-ext/range/lexer/separator'
18
+ require 'thefox-ext/range/lexer/operator'
19
+ require 'thefox-ext/range/lexer/block'
20
+ require 'thefox-ext/range/lexer/block_down'
21
+ require 'thefox-ext/range/lexer/block_up'
22
+ require 'thefox-ext/range/lexer/block_stack'
23
+ require 'thefox-ext/range/lexer/range'
24
+ require 'thefox-ext/range/lexer/interval'
25
+ require 'thefox-ext/range/lexer/number'
@@ -63,71 +63,4 @@ class String
63
63
  self.force_encoding('ISO-8859-1').encode('UTF-8')
64
64
  end
65
65
  end
66
-
67
- # Resolve a range string to an array.
68
- # A range string can be like '1, 3..5, 9-11, 12+, 14++, 17+++'.
69
- # Which will be resolved to [1, 3, 4, 5, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20].
70
- def resolve_range(prefix = '')
71
- # puts '-> resolve_range: %s {%s}' % [self, prefix]
72
-
73
- rv = Array.new
74
-
75
- items1 = self.split(',')
76
- # pp items1
77
-
78
- items2 = []
79
- is_sub_range = false
80
- sub_item = []
81
- items1.each do |item|
82
- if item.count('{') > 0
83
- is_sub_range = true
84
- end
85
- if is_sub_range
86
- sub_item.push(item)
87
- else
88
- items2.push(item)
89
- end
90
- if item.count('}') > 0
91
- is_sub_range = false
92
- items2.push(sub_item.join(','))
93
- sub_item = []
94
- end
95
- end
96
-
97
- # pp items2
98
-
99
- items2.map{ |item|
100
- item_striped = item.strip
101
- if range_match = item_striped.match(/(\d+)\{([\d\-\+,]+)\}/)
102
- range_match[2].resolve_range(range_match[1])
103
- elsif /\.\./.match(item_striped) # ( . )( . ) <--- BOOBS
104
- Range.new(*item_striped.split('..', 2).map{ |range| range.to_i })
105
- elsif /-/.match(item_striped)
106
- Range.new(*item_striped.split('-', 2).map{ |range| range.to_i })
107
- elsif /\+/.match(item_striped)
108
- items = item_striped.split('+')
109
- range_begin = items[0].to_i
110
- range_end = range_begin + item_striped.count('+')
111
- Range.new(range_begin, range_end)
112
- else
113
- item_striped.to_i
114
- end
115
- }.each{ |range|
116
- if range.is_a?(Range)
117
- rv.push(*range.to_a)
118
- elsif range.is_a?(Array)
119
- rv.push(*range)
120
- else
121
- rv << range
122
- end
123
- }
124
-
125
- if !prefix.empty?
126
- rv = rv.map { |i|
127
- (prefix + i.to_s).to_i
128
- }
129
- end
130
-
131
- rv
132
- end
133
66
  end
@@ -0,0 +1,69 @@
1
+
2
+ module TheFox
3
+ module Range
4
+ module Lexer
5
+ class Base
6
+ def initialize(symbole = nil)
7
+ # puts '-> Base.initialize'
8
+ @symbole = symbole
9
+ @prev_item = nil
10
+ @next_item = nil
11
+
12
+ @parent_item = nil
13
+ @children = []
14
+ end
15
+
16
+ def chain(item)
17
+ self.next_item = item
18
+ item.prev_item = self
19
+ end
20
+
21
+ def symbole()
22
+ @symbole
23
+ end
24
+
25
+ def prev_item()
26
+ @prev_item
27
+ end
28
+ def prev_item=(prev_item)
29
+ @prev_item = prev_item
30
+ end
31
+
32
+ def next_item()
33
+ @next_item
34
+ end
35
+ def next_item=(next_item)
36
+ @next_item = next_item
37
+ end
38
+
39
+ def parent_item()
40
+ @parent_item
41
+ end
42
+ def parent_item=(parent_item)
43
+ @parent_item = parent_item
44
+ end
45
+ def has_parent_item()
46
+ !@parent_item.nil?
47
+ end
48
+
49
+ def children()
50
+ @children
51
+ end
52
+ def add_child(child)
53
+ @children.push(child)
54
+ end
55
+ def has_children()
56
+ @children.length > 1
57
+ end
58
+
59
+ def dup()
60
+ # puts '-> Base.dup'
61
+ o = super()
62
+ o.prev_item = nil
63
+ o.next_item = nil
64
+ o
65
+ end
66
+ end # Base
67
+ end # Lexer
68
+ end # Range
69
+ end # TheFox
@@ -0,0 +1,10 @@
1
+
2
+ module TheFox
3
+ module Range
4
+ module Lexer
5
+ # { }
6
+ class Block < Scope
7
+ end # Block
8
+ end # Lexer
9
+ end # Range
10
+ end # TheFox
@@ -0,0 +1,21 @@
1
+
2
+ module TheFox
3
+ module Range
4
+ module Lexer
5
+ # {
6
+ class BlockDown < Block
7
+ def initialize(level)
8
+ super()
9
+ # puts '-> BlockDown.initialize(%d)' % [level]
10
+ @level = level
11
+ end
12
+
13
+ # :nocov:
14
+ def inspect()
15
+ 'BlockDown(%d)' % [@level]
16
+ end
17
+ # :nocov:
18
+ end # BlockDown
19
+ end # Lexer
20
+ end # Range
21
+ end # TheFox
@@ -0,0 +1,44 @@
1
+
2
+ require 'pp'
3
+
4
+ module TheFox
5
+ module Range
6
+ module Lexer
7
+ # 0123456789
8
+ class BlockStack
9
+ def initialize()
10
+ # puts '-> BlockStack.initialize()'
11
+ @stack = []
12
+ end
13
+
14
+ # :nocov:
15
+ def inspect()
16
+ 'BlockStack(%d)' % [@stack.length]
17
+ end
18
+ # :nocov:
19
+
20
+ def push(item)
21
+ @stack.push(item)
22
+ end
23
+
24
+ def pop()
25
+ @stack.pop
26
+ end
27
+
28
+ def curr()
29
+ @stack.last
30
+ end
31
+
32
+ def length()
33
+ @stack.length
34
+ end
35
+
36
+ def add_child(item)
37
+ if !@stack.last.nil? && !item.nil?
38
+ @stack.last.add_child(item)
39
+ end
40
+ end
41
+ end # BlockStack
42
+ end # Lexer
43
+ end # Range
44
+ end # TheFox
@@ -0,0 +1,21 @@
1
+
2
+ module TheFox
3
+ module Range
4
+ module Lexer
5
+ # }
6
+ class BlockUp < Block
7
+ def initialize(level)
8
+ super()
9
+ # puts '-> BlockUp.initialize(%d)' % [level]
10
+ @level = level
11
+ end
12
+
13
+ # :nocov:
14
+ def inspect()
15
+ 'BlockUp(%d)' % [@level]
16
+ end
17
+ # :nocov:
18
+ end # BlockUp
19
+ end # Lexer
20
+ end # Range
21
+ end # TheFox
@@ -0,0 +1,32 @@
1
+
2
+ module TheFox
3
+ module Range
4
+ module Lexer
5
+ # /n
6
+ class Interval < Base
7
+ def initialize()
8
+ super()
9
+ # puts '-> Interval.initialize()'
10
+ @number = nil
11
+ end
12
+
13
+ # :nocov:
14
+ def inspect()
15
+ if @number.nil?
16
+ 'Interval()'
17
+ else
18
+ 'Interval(%s)' % [@number.inspect]
19
+ end
20
+ end
21
+ # :nocov:
22
+
23
+ def number=(number)
24
+ @number = number
25
+ end
26
+ def number()
27
+ @number
28
+ end
29
+ end # Interval
30
+ end # Lexer
31
+ end # Range
32
+ end # TheFox
@@ -0,0 +1,284 @@
1
+
2
+ require 'pp'
3
+
4
+ module TheFox
5
+ module Range
6
+ module Lexer
7
+ class Lexer
8
+ def initialize(chars)
9
+ # puts '-> Lexer.initialize'
10
+ @chars = chars
11
+ # pp @chars
12
+ end
13
+
14
+ def resolve()
15
+ # puts
16
+ # puts '-> Lexer.resolve L1'
17
+
18
+ position = 0
19
+ prev_item = nil
20
+ block_level = 0
21
+ items1 = []
22
+ @chars.each do |char|
23
+ position += 1
24
+
25
+ curr_item = case char
26
+ when ','
27
+ Separator.new()
28
+ when '{'
29
+ block_level += 1
30
+ BlockDown.new(block_level)
31
+ when '}'
32
+ org_level = block_level
33
+ block_level -= 1
34
+ BlockUp.new(org_level)
35
+ when '+'
36
+ Operator.new()
37
+ when '-', '.'
38
+ Range.new(char)
39
+ when '/'
40
+ Interval.new()
41
+ when '0'..'9'
42
+ Number.new(char)
43
+ else
44
+ raise 'Unknown character at position %d: %s' % [position, char]
45
+ end
46
+
47
+ if !prev_item.nil?
48
+ prev_item.chain(curr_item)
49
+ end
50
+ items1.push(curr_item)
51
+ prev_item = curr_item
52
+ end
53
+
54
+ # pp items1.map{ |item| item.inspect }
55
+
56
+ # puts
57
+ # puts '-> Lexer.resolve L2'
58
+ curr_item = nil
59
+ prev_item = nil
60
+ items2 = []
61
+ items1.each do |item|
62
+ # puts '--> L2 item: %s' % [item.inspect]
63
+
64
+ append_dup = false
65
+
66
+ case item
67
+ when Number
68
+ if curr_item.nil?
69
+ # New Number
70
+ curr_item = item.dup
71
+ if !prev_item.nil?
72
+ prev_item.chain(curr_item)
73
+ end
74
+ items2.push(curr_item)
75
+ prev_item = curr_item
76
+ else
77
+ # Append Number
78
+ if curr_item.is_a?(Number)
79
+ curr_item.append(item.char)
80
+ else
81
+ raise 'Do not know what to do'
82
+ end
83
+ end
84
+ when Range
85
+ if prev_item.is_a?(Range) && prev_item.symbole == '.' && item.symbole == '.'
86
+ # skip
87
+ else
88
+ append_dup = true
89
+ end
90
+ else
91
+ # puts '--> L2 ELSE'
92
+
93
+ append_dup = true
94
+ end
95
+
96
+ if append_dup
97
+ curr_item = item.dup
98
+ if !prev_item.nil?
99
+ prev_item.chain(curr_item)
100
+ end
101
+ items2.push(curr_item)
102
+ prev_item = curr_item
103
+
104
+ curr_item = nil
105
+ end
106
+ end
107
+
108
+ # pp items2.map{ |item| item.inspect }
109
+
110
+ # puts
111
+ # puts '-> Lexer.resolve L3'
112
+ append_dub_f = nil
113
+ append_prev_f = nil
114
+ prev_item = nil
115
+ block_stack = BlockStack.new
116
+ items3 = []
117
+ items2.each do |item|
118
+ # puts '--> L3 %20s bs=%d' % [item.inspect, block_stack.length]
119
+
120
+ append_dup = false
121
+ append_prev = false
122
+
123
+ case item
124
+ when Number
125
+ if item.next_item.is_a?(Range) || item.prev_item.is_a?(Range) || item.prev_item.is_a?(Interval)
126
+ # skip
127
+ else
128
+ append_dup = true
129
+ end
130
+ when Range
131
+ if item.prev_item.is_a?(Number) && item.next_item.is_a?(Number)
132
+ # puts '--> Range normal'
133
+ append_dub_f = -> (curr_item){
134
+ curr_item.left_item = item.prev_item.dup
135
+ curr_item.right_item = item.next_item.dup
136
+
137
+ curr_item.left_item.parent_item = block_stack.curr
138
+ curr_item.right_item.parent_item = block_stack.curr
139
+
140
+ block_stack.add_child(curr_item.left_item)
141
+ block_stack.add_child(curr_item.right_item)
142
+ }
143
+ append_dup = true
144
+ else
145
+ raise 'Invalid Range: %s %s' % [
146
+ item.prev_item.inspect,
147
+ item.next_item.inspect,
148
+ ]
149
+ end
150
+ when Interval
151
+ if !item.next_item.is_a?(Number)
152
+ raise 'Invalid Interval: %s' % [item.next_item.inspect]
153
+ end
154
+
155
+ append_dub_f = ->(curr_item){ curr_item.number = item.next_item.dup }
156
+ append_dup = true
157
+ when Operator
158
+ if prev_item.is_a?(Number)
159
+ append_prev_f = -> (curr_item){ curr_item.inc }
160
+ append_prev = true
161
+ end
162
+ when BlockDown
163
+ #block_stack.push(item.dup)
164
+ append_dub_f = ->(curr_item){ block_stack.push(curr_item) }
165
+ append_dup = true
166
+ when BlockUp
167
+ block_stack.pop
168
+ append_dup = true
169
+ else
170
+ # puts '--> L3 ELSE'
171
+ append_dup = true
172
+ end
173
+
174
+ # Append Dup
175
+ if append_dup
176
+ # Dup
177
+ curr_item = item.dup
178
+ # Function
179
+ if !append_dub_f.nil?
180
+ append_dub_f.call(curr_item)
181
+ append_dub_f = nil
182
+ end
183
+ # Chain
184
+ if !prev_item.nil?
185
+ prev_item.chain(curr_item)
186
+ end
187
+ # Block
188
+ if !item.is_a?(Block)
189
+ # puts '---> set Parent: %s' % [block_stack.curr.inspect]
190
+ curr_item.parent_item = block_stack.curr
191
+ block_stack.add_child(curr_item)
192
+ end
193
+ # Append
194
+ items3.push(curr_item)
195
+ # Prev Item
196
+ prev_item = curr_item
197
+ end
198
+
199
+ # Append Prev
200
+ if append_prev && !prev_item.nil?
201
+ # Dup
202
+ curr_item = prev_item.dup
203
+ # Function
204
+ if !append_prev_f.nil?
205
+ append_prev_f.call(curr_item)
206
+ append_prev_f = nil
207
+ end
208
+ # Chain
209
+ prev_item.chain(curr_item)
210
+ # Block
211
+ if !item.is_a?(Block)
212
+ curr_item.parent_item = block_stack.curr
213
+ block_stack.add_child(curr_item)
214
+ end
215
+ # Append
216
+ items3.push(curr_item)
217
+ # Prev Item
218
+ prev_item = curr_item
219
+ end
220
+
221
+ # Block
222
+ if item.is_a?(Block)
223
+ # puts '--> L3 set parent block for block'
224
+ item.parent_item = block_stack.curr
225
+ block_stack.add_child(item)
226
+ end
227
+ end
228
+
229
+ # pp items3.map{ |item| item.inspect }
230
+
231
+ # puts
232
+ # puts '-> Lexer.resolve L4 [convert to int]'
233
+ items4 = []
234
+ items3.each do |item|
235
+ # puts '--> L4 %20s %20s c: %d' % [item.inspect, item.parent_item.inspect, item.children.length]
236
+
237
+ case item
238
+ when Number
239
+ if item.next_item.is_a?(BlockDown)
240
+ # skip
241
+ # puts '---> skip'
242
+ else
243
+ items4.push(item.char.to_i)
244
+ end
245
+ when Range
246
+ r_begin = item.left_item.char.to_i
247
+ r_end = item.right_item.char.to_i
248
+ r = ::Range.new(r_begin, r_end)
249
+
250
+ if item.next_item.is_a?(Interval)
251
+ # Interval Range
252
+ n = item.next_item.number.char.to_i
253
+ c = 0
254
+ r.each do |i|
255
+ if c == 0
256
+ items4.push(i)
257
+ end
258
+ c += 1
259
+ if c == n
260
+ c = 0
261
+ end
262
+ end
263
+ else
264
+ # Normal Range
265
+ items4.push(*r.to_a)
266
+ end
267
+ when Interval
268
+ # puts '---> skip Interval'
269
+ when Separator
270
+ # puts '---> skip Separator'
271
+ when Block
272
+ # puts '---> skip Block'
273
+ else
274
+ raise 'Implementation missing for: %s' % [item.inspect]
275
+ end
276
+ end
277
+
278
+ # pp items4
279
+ items4
280
+ end
281
+ end # Lexer
282
+ end # Lexer
283
+ end # Range
284
+ end # TheFox
@@ -0,0 +1,56 @@
1
+
2
+ require 'pp'
3
+
4
+ module TheFox
5
+ module Range
6
+ module Lexer
7
+ # 0123456789
8
+ class Number < Base
9
+ def initialize(char)
10
+ super()
11
+ # puts '-> Number.initialize(%s)' % [char]
12
+ @char = char
13
+ end
14
+
15
+ # :nocov:
16
+ def inspect()
17
+ 'Number(%s,^%s)' % [@char, @parent_item.inspect]
18
+ end
19
+ # :nocov:
20
+
21
+ def char()
22
+ # puts '-> %s.char' % [self.inspect]
23
+ if self.has_parent_item
24
+ # puts '-> %s.char has parent' % [self.inspect]
25
+ if self.parent_item.is_a?(Block)
26
+ # puts '-> %s.char parent is a %s' % [self.inspect, self.parent_item.inspect]
27
+ if self.parent_item.prev_item.is_a?(Number)
28
+ # puts '-> %s.char parent Prev is a %s' % [self.inspect, self.parent_item.prev_item.inspect]
29
+ '%s%s' % [self.parent_item.prev_item.char, @char]
30
+ else
31
+ raise 'Parent Prev item for %s is not a Block: %s' % [
32
+ self.inspect,
33
+ self.parent_item.prev_item.inspect,
34
+ ]
35
+ end
36
+ else
37
+ raise 'Parent item for %s is not a Block: %s' % [self.inspect, self.parent_item.inspect]
38
+ end
39
+ else
40
+ # puts '-> %s.char char' % [self.inspect]
41
+ @char
42
+ end
43
+ end
44
+
45
+ def append(char)
46
+ @char += char
47
+ end
48
+
49
+ def inc()
50
+ f = '%%0%dd' % [@char.length]
51
+ @char = f % [@char.to_i + 1]
52
+ end
53
+ end # Number
54
+ end # Lexer
55
+ end # Range
56
+ end # TheFox
@@ -0,0 +1,20 @@
1
+
2
+ module TheFox
3
+ module Range
4
+ module Lexer
5
+ # +
6
+ class Operator < Base
7
+ def initialize()
8
+ super()
9
+ # puts '-> Operator.initialize'
10
+ end
11
+
12
+ # :nocov:
13
+ def inspect()
14
+ 'Operator()'
15
+ end
16
+ # :nocov:
17
+ end # Operator
18
+ end # Lexer
19
+ end # Range
20
+ end # TheFox
@@ -0,0 +1,41 @@
1
+
2
+ module TheFox
3
+ module Range
4
+ module Lexer
5
+ # -
6
+ class Range < Base
7
+ def initialize(symbole)
8
+ super(symbole)
9
+ # puts '-> Range.initialize(%s)' % [symbole]
10
+
11
+ @left_item = nil
12
+ @right_item = nil
13
+ end
14
+
15
+ def left_item()
16
+ @left_item
17
+ end
18
+ def left_item=(left_item)
19
+ @left_item = left_item
20
+ end
21
+
22
+ def right_item()
23
+ @right_item
24
+ end
25
+ def right_item=(right_item)
26
+ @right_item = right_item
27
+ end
28
+
29
+ # :nocov:
30
+ def inspect()
31
+ if !@left_item.nil? && !@right_item.nil?
32
+ 'Range(%s, %s, %s)' % [@symbole, @left_item.inspect, @right_item.inspect]
33
+ else
34
+ 'Range(%s)' % [@symbole]
35
+ end
36
+ end
37
+ # :nocov:
38
+ end # Range
39
+ end # Lexer
40
+ end # Range
41
+ end # TheFox
@@ -0,0 +1,9 @@
1
+
2
+ module TheFox
3
+ module Range
4
+ module Lexer
5
+ class Scope < Base
6
+ end # Scope
7
+ end # Lexer
8
+ end # Range
9
+ end # TheFox
@@ -0,0 +1,19 @@
1
+
2
+ module TheFox
3
+ module Range
4
+ module Lexer
5
+ class Separator < Scope
6
+ def initialize()
7
+ super()
8
+ # puts '-> Separator.initialize()'
9
+ end
10
+
11
+ # :nocov:
12
+ def inspect()
13
+ 'Separator'
14
+ end
15
+ # :nocov:
16
+ end # Separator
17
+ end # Lexer
18
+ end # Range
19
+ end # TheFox
@@ -0,0 +1,39 @@
1
+
2
+ require 'pp'
3
+
4
+ module TheFox
5
+ module Range
6
+ # Resolve a range string to an array.
7
+ # A range string can be like '1, 3..5, 9-11, 12+, 14++, 17+++'.
8
+ # Which will be resolved to [1, 3, 4, 5, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20].
9
+ # '1' -> [1]
10
+ # '1,3,99' -> [1, 3, 99]
11
+ # '1-5' -> [1, 2, 3, 4, 5]
12
+ # '1+,5++' -> [1, 2, 5, 6, 7]
13
+ # '1-10/2' -> [1, 3, 5, 7, 9]
14
+ # '1{1}' -> [11]
15
+ # '1{5-7}' -> [15, 16, 17]
16
+ # '1{1,02}' -> [11, 102]
17
+ # '2{3{4,5},6}' -> [234, 235, 26]
18
+ # '1-3/1' -> [1, 2, 3]
19
+ # '1-10/2' -> [1, 3, 5, 7, 9]
20
+ # '2{10-20/2}' -> [210, 212, 214, 216, 218, 220]
21
+ class Resolver
22
+ def initialize(original = nil)
23
+ # puts '-> TheFox::Range::Resolver.initialize'
24
+ @original = original
25
+ end
26
+
27
+ def to_a
28
+ # puts '-> TheFox::Range::Resolver.to_a'
29
+
30
+ if @original.is_a?(String)
31
+ lexer = Lexer::Lexer.new(@original.split(''))
32
+ lexer.resolve
33
+ else
34
+ []
35
+ end
36
+ end
37
+ end # Resolver
38
+ end # Range
39
+ end # TheFox
@@ -1,8 +1,8 @@
1
1
 
2
2
  module TheFox
3
3
  module Ext
4
- VERSION = '1.9.0'
5
- DATE = '2021-04-05'
4
+ VERSION = '2.0.0'
5
+ DATE = '2021-04-19'
6
6
  HOMEPAGE = 'https://github.com/TheFox/ext.rb'
7
7
  end
8
8
  end
data/thefox-ext.gemspec CHANGED
@@ -19,9 +19,9 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.files = `git ls-files -z`.split("\x0").reject{ |f| f.match(%r{^(test|spec|features)/}) }
21
21
  spec.require_paths = ['lib']
22
- spec.required_ruby_version = ['>=2.3.0']
22
+ spec.required_ruby_version = ['>=2.4.0']
23
23
 
24
24
  spec.add_development_dependency 'minitest', '~>5.8'
25
- spec.add_development_dependency 'simplecov', '~>0.13'
25
+ spec.add_development_dependency 'simplecov', '~>0.18'
26
26
  spec.add_development_dependency 'simplecov-phpunit', '~>1.0'
27
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thefox-ext
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Mayer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-05 00:00:00.000000000 Z
11
+ date: 2021-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.13'
33
+ version: '0.18'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.13'
40
+ version: '0.18'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: simplecov-phpunit
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -64,6 +64,7 @@ files:
64
64
  - ".github/workflows/release.yml"
65
65
  - ".gitignore"
66
66
  - CHANGELOG-v1.md
67
+ - CHANGELOG-v2.md
67
68
  - Gemfile
68
69
  - LICENSE
69
70
  - README.md
@@ -75,7 +76,6 @@ files:
75
76
  - bin/uninstall.sh
76
77
  - lib/thefox-ext.rb
77
78
  - lib/thefox-ext/console.rb
78
- - lib/thefox-ext/ext/array.rb
79
79
  - lib/thefox-ext/ext/date.rb
80
80
  - lib/thefox-ext/ext/false.rb
81
81
  - lib/thefox-ext/ext/hash.rb
@@ -83,6 +83,19 @@ files:
83
83
  - lib/thefox-ext/ext/nil.rb
84
84
  - lib/thefox-ext/ext/string.rb
85
85
  - lib/thefox-ext/ext/true.rb
86
+ - lib/thefox-ext/range/lexer/base.rb
87
+ - lib/thefox-ext/range/lexer/block.rb
88
+ - lib/thefox-ext/range/lexer/block_down.rb
89
+ - lib/thefox-ext/range/lexer/block_stack.rb
90
+ - lib/thefox-ext/range/lexer/block_up.rb
91
+ - lib/thefox-ext/range/lexer/interval.rb
92
+ - lib/thefox-ext/range/lexer/lexer.rb
93
+ - lib/thefox-ext/range/lexer/number.rb
94
+ - lib/thefox-ext/range/lexer/operator.rb
95
+ - lib/thefox-ext/range/lexer/range.rb
96
+ - lib/thefox-ext/range/lexer/scope.rb
97
+ - lib/thefox-ext/range/lexer/separator.rb
98
+ - lib/thefox-ext/range/resolver.rb
86
99
  - lib/thefox-ext/version.rb
87
100
  - thefox-ext.code-workspace
88
101
  - thefox-ext.gemspec
@@ -98,14 +111,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
98
111
  requirements:
99
112
  - - ">="
100
113
  - !ruby/object:Gem::Version
101
- version: 2.3.0
114
+ version: 2.4.0
102
115
  required_rubygems_version: !ruby/object:Gem::Requirement
103
116
  requirements:
104
117
  - - ">="
105
118
  - !ruby/object:Gem::Version
106
119
  version: '0'
107
120
  requirements: []
108
- rubygems_version: 3.2.3
121
+ rubygems_version: 3.2.15
109
122
  signing_key:
110
123
  specification_version: 4
111
124
  summary: Extended Ruby Classes
@@ -1,38 +0,0 @@
1
-
2
- class Array
3
-
4
- # DEPRECATED: will be removed in v1.10.0.
5
- def self.resolve_range_str(original_str, prefix = '')
6
- warn "[DEPRECATION] `Array.resolve_range_str` is deprecated. Please use `String.resolve_range` instead."
7
-
8
- rv = Array.new
9
- if !original_str.is_a?(String)
10
- return rv
11
- end
12
-
13
- original_str.split(',').map{ |item|
14
- item_striped = item.strip
15
- if /\.\./.match(item_striped) # ( . )( . ) <--- BOOBS
16
- Range.new(*item_striped.split('..', 2).map{ |range| range.to_i })
17
- elsif /-/.match(item_striped)
18
- Range.new(*item_striped.split('-', 2).map{ |range| range.to_i })
19
- elsif /\+/.match(item_striped)
20
- items = item_striped.split('+')
21
- range_begin = items[0].to_i
22
- range_end = range_begin + item_striped.count('+')
23
- Range.new(range_begin, range_end)
24
- else
25
- item_striped.to_i
26
- end
27
- }.each{ |range|
28
- if range.is_a?(Range)
29
- rv.push(*range.to_a)
30
- else
31
- rv << range
32
- end
33
- }
34
-
35
- rv
36
- end
37
-
38
- end