mobj 2.2.1 → 2.4.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.
data/README.md CHANGED
@@ -156,7 +156,7 @@ Matching stuff:
156
156
  ```ruby
157
157
  match = "Joe Bob".match(/(?<first_name>\w+) (?<first_name>)/)
158
158
 
159
- match.to_hash
159
+ match.to_h
160
160
  #=> Creates a hash of named captures
161
161
 
162
162
  match.first_name if match.first_name?
data/lib/ext/array.rb ADDED
@@ -0,0 +1,40 @@
1
+ module Mobj
2
+
3
+ class ::Array
4
+ alias includes? include?
5
+ alias contains? include?
6
+
7
+ def unempty?()
8
+ !empty?
9
+ end
10
+
11
+ alias_method :notempty?, :unempty?
12
+
13
+ def msum(initial = 0.0, op = :+, &block)
14
+ map(&:to_f).inject(initial, block ? block : op)
15
+ end
16
+
17
+ def mavg(&block)
18
+ msum(&block) / size
19
+ end
20
+
21
+ def values()
22
+ self
23
+ end
24
+
25
+ def sequester(crush = true)
26
+ if crush
27
+ compact.size <= 1 ? compact.first : self
28
+ else
29
+ size <= 1 ? first : self
30
+ end
31
+ end
32
+
33
+ def return_first(&block)
34
+ returned = nil
35
+ each { |item| break if (returned = block.call(item)) }
36
+ returned
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,32 @@
1
+ module Mobj
2
+
3
+ class ::BasicObject
4
+ def class
5
+ klass = class << self;
6
+ self
7
+ end
8
+ klass.superclass
9
+ end
10
+
11
+ def null!(*)
12
+ self
13
+ end
14
+
15
+ def nil!(*)
16
+ self
17
+ end
18
+
19
+ def itself()
20
+ self
21
+ end
22
+
23
+ def wrap(*args, &block)
24
+ instance_exec(*args, &block)
25
+ end
26
+
27
+ alias_method :alter, :wrap
28
+
29
+ end
30
+
31
+
32
+ end
data/lib/ext/class.rb ADDED
@@ -0,0 +1,17 @@
1
+ module Mobj
2
+
3
+ class ::Class
4
+ def object_methods()
5
+ (self.instance_methods(true) - Object.instance_methods(true)).sort
6
+ end
7
+
8
+ def class_methods()
9
+ (self.singleton_methods(true) - Object.singleton_methods(true)).sort
10
+ end
11
+
12
+ def defined_methods()
13
+ (class_methods | object_methods).sort
14
+ end
15
+ end
16
+
17
+ end
data/lib/ext/fixnum.rb ADDED
@@ -0,0 +1,9 @@
1
+ module Mobj
2
+
3
+ class ::Fixnum
4
+ def delimit(delim = ',')
5
+ to_s.split('').reverse.each_slice(3).to_a.map(&:join).join(delim).reverse
6
+ end
7
+ end
8
+
9
+ end
data/lib/ext/float.rb ADDED
@@ -0,0 +1,9 @@
1
+ module Mobj
2
+
3
+ class ::Float
4
+ def delimit(delim = ',')
5
+ "#{to_i.delimit(delim)}.#{to_s.to_s[/\.(\d+)$/, 1]}"
6
+ end
7
+ end
8
+
9
+ end
data/lib/ext/hash.rb ADDED
@@ -0,0 +1,74 @@
1
+ module Mobj
2
+
3
+ module HashEx
4
+
5
+ def ki(name)
6
+ name.to_s[/(.*?)[?!=]?$/, 1]
7
+ end
8
+
9
+ def ki?(name)
10
+ [name.sym, name.to_s, ki(name).sym, ki(name).to_s].any? { |k| key?(k) }
11
+ end
12
+
13
+ def symvert(key_converter = :itself, value_converter = key_converter)
14
+ each.with_object({}) do |(k, v), o|
15
+ key = if key_converter.is_a?(Proc)
16
+ key_converter.call(k, v)
17
+ elsif k.respond_to?(key_converter.sym)
18
+ k.__send__(key_converter.sym)
19
+ else
20
+ k
21
+ end
22
+
23
+ value = if value_converter.is_a?(Proc)
24
+ value_converter.arity == 1 ? value_converter.call(v) : value_converter.call(k, v)
25
+ elsif v.respond_to?(value_converter.sym)
26
+ v.__send__(value_converter.sym)
27
+ else
28
+ v
29
+ end
30
+
31
+ o[key] = value
32
+ end
33
+ end
34
+
35
+ def symvert!(key_converter = :itself, value_converter = key_converter)
36
+ replace(symvert(key_converter, value_converter))
37
+ end
38
+
39
+ def method_missing(name, *args, &block)
40
+ value = if name[-1] == '=' && args.size == 1
41
+ key = name[0...-1].sym
42
+ key = key.to_s if key?(key.to_s)
43
+ self[key] = args.sequester
44
+ elsif name[-1] == '?'
45
+ key = name[0...-1].sym
46
+ !!self[key, key.to_s]
47
+ elsif name[-1] == '!'
48
+ key = name[0...-1].sym
49
+ val = self[key.sym] || self[key.to_s]
50
+ if !val && (block || args.unempty?)
51
+ self[key] = val = (block ? block.call(*args) : args.sequester)
52
+ end
53
+ super unless val
54
+ else
55
+ self[name.sym] || self[name.to_s]
56
+ end
57
+ value ||= args.sequester unless args.empty?
58
+
59
+ return block ? block[value] : value
60
+ end
61
+ end
62
+
63
+ class ::Hash
64
+ include HashEx
65
+
66
+ alias :mlookup :[]
67
+ alias :mdef :default
68
+
69
+ def [](*fkeys)
70
+ fkeys.map { |key| mlookup(key) || fetch(key.sym) { fetch(key.to_s) { fetch(ki(key).sym) { fetch(ki(key).to_s) { mdef(key) } } } } }.sequester
71
+ end
72
+ end
73
+
74
+ end
@@ -0,0 +1,22 @@
1
+ module Mobj
2
+
3
+ module MatchEx
4
+ def to_h
5
+ Hash[names.map(&:sym).zip(captures)]
6
+ end
7
+
8
+ def method_missing(name, *args, &block)
9
+ if name[-1] == '?' && names.includes?(name[0...-1])
10
+ return to_h[name[0...-1].sym]
11
+ elsif names.includes?(name.to_s)
12
+ return to_h[name.sym]
13
+ end
14
+ super
15
+ end
16
+ end
17
+
18
+ class ::MatchData
19
+ include MatchEx
20
+ end
21
+
22
+ end
data/lib/ext/nil.rb ADDED
@@ -0,0 +1,56 @@
1
+ module Mobj
2
+
3
+ class ::NilClass
4
+ MOBJ_NULL_REGION_BEGIN = __LINE__
5
+
6
+ def __mobj__caller()
7
+ caller.find do |frame|
8
+ (file, line) = frame.split(":")
9
+ file != __FILE__ || !(MOBJ_NULL_REGION_BEGIN..MOBJ_NULL_REGION_END).cover?(line.to_i)
10
+ end
11
+ end
12
+
13
+ def null?(*)
14
+ @@null ||= nil
15
+ @@null && @@null == __mobj__caller
16
+ end
17
+
18
+ def null!(*)
19
+ @@null = __mobj__caller
20
+ self
21
+ end
22
+
23
+ def nil!(*)
24
+ @@null = nil
25
+ self
26
+ end
27
+
28
+ def method_missing(name, *args, &block)
29
+ if null?
30
+ self
31
+ else
32
+ nil!
33
+ super
34
+ end
35
+ end
36
+
37
+ alias_method :try?, :null!
38
+
39
+ MOBJ_NULL_REGION_END = __LINE__
40
+
41
+ def attempt(value=true)
42
+ Forwarder.new do |name, *args, &block|
43
+ if self.methods(true).include? name
44
+ self.__send__(name, *args, &block)
45
+ elsif value.is_a?(Proc)
46
+ value.call([name] + args, &block)
47
+ elsif value.is_a?(Hash) && value.ki?(name)
48
+ value[name].when.is_a?(Proc).call(*args, &block)
49
+ else
50
+ value
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ end
data/lib/ext/object.rb ADDED
@@ -0,0 +1,88 @@
1
+ module Mobj
2
+
3
+ class ::Object
4
+ alias responds_to? respond_to?
5
+
6
+ def sym()
7
+ respond_to?(:to_sym) ? to_sym : to_s.to_sym
8
+ end
9
+
10
+ def __mobj__root()
11
+ __mobj__parent.nil? || __mobj__parent == self ? self : __mobj__parent.__mobj__root
12
+ end
13
+
14
+ def __mobj__reparent()
15
+ values.each { |v| v.__mobj__parent(self); v.__mobj__reparent } if respond_to? :values
16
+ end
17
+
18
+ def __mobj__parent?()
19
+ !@__mobj__parent.nil?
20
+ end
21
+
22
+ def __mobj__parent(rent = :"__mobj__parent")
23
+ unless rent == :"__mobj__parent"
24
+ @__mobj__parent = rent == self ? nil : rent
25
+ end
26
+ @__mobj__parent
27
+ end
28
+
29
+ def attempt(value=:root)
30
+ Forwarder.new do |name, *args, &block|
31
+ if self.methods(true).include? name ##//use respond to?
32
+ self.__send__(name, *args, &block)
33
+ elsif value.is_a?(Proc)
34
+ value.call([name] + args, &block)
35
+ elsif value.is_a?(Hash) && value.ki?(name)
36
+ value[name].when.is_a?(Proc).call(*args, &block)
37
+ else
38
+ value == :root ? self : value
39
+ end
40
+ end
41
+ end
42
+
43
+ def try?(default=nil, &block)
44
+ Forwarder.new do |name, *args, &fblock|
45
+ if methods(true).include?(name)
46
+ __send__(name, *args, &fblock)
47
+ elsif is_a?(Hash) && ki?(name)
48
+ self[name]
49
+ end || (block ? instance_exec(*[*default], &block) : default) || nil.null!
50
+ end
51
+ end
52
+
53
+ alias_method :ifnil, :try?
54
+
55
+ def when
56
+ Forwarder.new do |name, *args, &block|
57
+ if methods.include?(name) && __send__(name, *args, &block)
58
+ thn = Forwarder.new do |name, *args, &block|
59
+ if name.sym == :then
60
+ thn
61
+ else
62
+ ret = __send__(name, *args, &block)
63
+ ret.define_singleton_method(:else) { Forwarder.new { ret } }
64
+ ret
65
+ end
66
+ end
67
+ else
68
+ Forwarder.new do |name|
69
+ if name.sym == :then
70
+ els = Forwarder.new do |name|
71
+ if name.sym == :else
72
+ Forwarder.new { |name, *args, &block| __send__(name, *args, &block) }
73
+ else
74
+ els
75
+ end
76
+ end
77
+ else
78
+ self
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ alias_method :if?, :when
86
+ end
87
+
88
+ end
data/lib/ext/string.rb ADDED
@@ -0,0 +1,80 @@
1
+ require 'mobj'
2
+
3
+ module Mobj
4
+
5
+ class ::String
6
+
7
+ def matches(regexp)
8
+ start = 0
9
+ matches = []
10
+ while (match = match(regexp, start))
11
+ start = match.end(0)
12
+ matches << match
13
+ yield match if block_given?
14
+ end
15
+ matches
16
+ end
17
+
18
+ def walk(obj)
19
+ tokenize.walk(obj)
20
+ end
21
+
22
+ def tokenize
23
+ tokens = []
24
+
25
+ lit = /\~(?<literal>[^\.]+)/
26
+ regex = /\/(?<regex>.*?(?<!\\))\//
27
+ lookup = /\{\{(?<lookup>.*?)\}\}/
28
+ up = /(?<up>\^)/
29
+ path = /(?<path>[^\.\[]+)/
30
+ indexes = /(?<indexes>[\d\+\.,\s-]+)/
31
+
32
+ matcher = /#{lit}|#{regex}|#{lookup}|#{up}|#{path}(?:\[#{indexes}\])?/
33
+
34
+ matches(matcher) do |match|
35
+ if match.literal?
36
+ tokens << Mobj::Token.new(:literal, match.literal)
37
+ elsif match.lookup?
38
+ tokens << Mobj::Token.new(:lookup, match.lookup.tokenize)
39
+ elsif match.regex?
40
+ tokens << Mobj::Token.new(:regex, Regexp.new(match.regex))
41
+ elsif match.up?
42
+ tokens << Mobj::Token.new(:up)
43
+ elsif match.path?
44
+ eachs = match.path.split(/\s*,\s*/)
45
+ ors = match.path.split(/\s*\|\s*/)
46
+ ands = match.path.split(/\s*\&\s*/)
47
+ if eachs.size > 1
48
+ tokens << Mobj::Token.new(:each, eachs.map { |token| token.tokenize() })
49
+ elsif ands.size > 1
50
+ tokens << Mobj::Token.new(:all, ands.map { |token| token.tokenize() })
51
+ elsif ors.size > 1
52
+ tokens << Mobj::Token.new(:any, ors.map { |token| token.tokenize() })
53
+ end
54
+
55
+ unless ands.size + ors.size + eachs.size > 3
56
+ options = {}
57
+ index_matcher = /\s*(?<low>\d+)\s*(?:(?:\.\s*\.\s*(?<ex>\.)?\s*|-?)\s*(?<high>-?\d+|\+))?\s*/
58
+
59
+ options[:indexes] = match.indexes.matches(index_matcher).map do |index|
60
+ if index.high?
61
+ Range.new(index.low.to_i, (index.high == "+" ? -1 : index.high.to_i), index.ex?)
62
+ else
63
+ index.low.to_i
64
+ end
65
+ end if match.indexes?
66
+
67
+ if match.path[0] == '!'
68
+ tokens << Mobj::Token.new(:inverse, Token.new(:path, match.path[1..-1].sym, options))
69
+ else
70
+ tokens << Mobj::Token.new(:path, match.path.sym, options)
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ tokens.size == 1 ? tokens.first : Mobj::Token.new(:root, tokens)
77
+ end
78
+ end
79
+
80
+ end
data/lib/ext/symbol.rb ADDED
@@ -0,0 +1,9 @@
1
+ module Mobj
2
+
3
+ class ::Symbol
4
+ def walk(obj)
5
+ to_s.walk(obj)
6
+ end
7
+ end
8
+
9
+ end
data/lib/mobj.rb CHANGED
@@ -1,29 +1,9 @@
1
- module Mobj
2
-
3
- class ::BasicObject
4
- def class
5
- klass = class << self; self end
6
- klass.superclass
7
- end
8
- def null!(*) self end
9
- def nil!(*) self end
10
- def itself() self end
11
- def alter(*args, &block) instance_exec(*args, &block) end
12
- alias_method :o!, :alter
13
-
14
- end
15
-
16
- class ::Fixnum
17
- def delimit(delim = ',')
18
- to_s.split('').reverse.each_slice(3).to_a.map(&:join).join(delim).reverse
19
- end
20
- end
1
+ Dir["#{File.dirname(__FILE__)}/ext/*.rb"].each do |f|
2
+ exclude = ENV['MOBJ_EXCLUDE']
3
+ require f unless (exclude && f.match(exclude))
4
+ end
21
5
 
22
- class ::Float
23
- def delimit(delim = ',')
24
- "#{to_i.delimit(delim)}.#{to_s.to_s[/\.(\d+)$/, 1]}"
25
- end
26
- end
6
+ module Mobj
27
7
 
28
8
  class Forwarder < ::BasicObject
29
9
  attr_accessor :root, :handler
@@ -31,248 +11,6 @@ module Mobj
31
11
  def method_missing(name, *args, &block) handler.call(name, *args, &block) end
32
12
  end
33
13
 
34
- class ::Object
35
- alias responds_to? respond_to?
36
- def sym() respond_to?(:to_sym) ? to_sym : to_s.to_sym end
37
- def __mobj__root() __mobj__parent.nil? || __mobj__parent == self ? self : __mobj__parent.__mobj__root end
38
- def __mobj__reparent() values.each { |v| v.__mobj__parent(self); v.__mobj__reparent } if respond_to? :values end
39
- def __mobj__parent?() !@__mobj__parent.nil? end
40
- def __mobj__parent(rent = :"__mobj__parent")
41
- unless rent == :"__mobj__parent"
42
- @__mobj__parent = rent == self ? nil : rent
43
- end
44
- @__mobj__parent
45
- end
46
- def attempt(value=:root)
47
- Forwarder.new do |name, *args, &block|
48
- if self.methods(true).include? name ##//use respond to?
49
- self.__send__(name, *args, &block)
50
- elsif value.is_a?(Proc)
51
- value.call([name] + args, &block)
52
- elsif value.is_a?(Hash) && value.ki?(name)
53
- value[name].when.is_a?(Proc).call(*args, &block)
54
- else
55
- value == :root ? self : value
56
- end
57
- end
58
- end
59
-
60
- def try?(default=nil, &block)
61
- Forwarder.new do |name, *args, &fblock|
62
- if methods(true).include?(name)
63
- __send__(name, *args, &fblock)
64
- elsif is_a?(Hash) && ki?(name)
65
- self[name]
66
- end || (block ? instance_exec(*[*default], &block) : default) || nil.null!
67
- end
68
- end
69
-
70
- alias_method :ifnil, :try?
71
-
72
- def when
73
- Forwarder.new do |name, *args, &block|
74
- if methods.include?(name) && __send__(name, *args, &block)
75
- thn = Forwarder.new do |name, *args, &block|
76
- if name.sym == :then
77
- thn
78
- else
79
- ret = __send__(name, *args, &block)
80
- ret.define_singleton_method(:else) { Forwarder.new { ret } }
81
- ret
82
- end
83
- end
84
- else
85
- Forwarder.new do |name|
86
- if name.sym == :then
87
- els = Forwarder.new do |name|
88
- if name.sym == :else
89
- Forwarder.new { |name, *args, &block| __send__(name, *args, &block) }
90
- else
91
- els
92
- end
93
- end
94
- else
95
- self
96
- end
97
- end
98
- end
99
- end
100
- end
101
- alias_method :if?, :when
102
- end
103
-
104
- class ::NilClass
105
- MOBJ_NULL_REGION_BEGIN = __LINE__
106
- def __mobj__caller()
107
- caller.find do |frame|
108
- (file, line) = frame.split(":")
109
- file != __FILE__ || !(MOBJ_NULL_REGION_BEGIN..MOBJ_NULL_REGION_END).cover?(line.to_i)
110
- end
111
- end
112
- def null?(*)
113
- @@null ||= nil
114
- @@null && @@null == __mobj__caller
115
- end
116
- def null!(*)
117
- @@null = __mobj__caller
118
- self
119
- end
120
- def nil!(*)
121
- @@null = nil
122
- self
123
- end
124
- def method_missing(name, *args, &block)
125
- if null?
126
- self
127
- else
128
- nil!
129
- super
130
- end
131
- end
132
- alias_method :try?, :null!
133
-
134
- MOBJ_NULL_REGION_END = __LINE__
135
-
136
- def attempt(value=true)
137
- Forwarder.new do |name, *args, &block|
138
- if self.methods(true).include? name
139
- self.__send__(name, *args, &block)
140
- elsif value.is_a?(Proc)
141
- value.call([name] + args, &block)
142
- elsif value.is_a?(Hash) && value.ki?(name)
143
- value[name].when.is_a?(Proc).call(*args, &block)
144
- else
145
- value
146
- end
147
- end
148
- end
149
- end
150
-
151
- class ::Class
152
- def object_methods() (self.instance_methods(true) - Object.instance_methods(true)).sort end
153
- def class_methods() (self.singleton_methods(true) - Object.singleton_methods(true)).sort end
154
- def defined_methods() (class_methods | object_methods).sort end
155
- end
156
-
157
- class ::Array
158
- alias includes? include?
159
- alias contains? include?
160
-
161
- def unempty?() !empty? end
162
- alias_method :notempty?, :unempty?
163
-
164
- def msum(initial = 0.0, op = :+, &block)
165
- map(&:to_f).inject(initial, block ? block : op)
166
- end
167
-
168
- def mavg(&block)
169
- msum(&block) / size
170
- end
171
-
172
- def values() self end
173
- def sequester(crush = true)
174
- if crush
175
- compact.size <= 1 ? compact.first : self
176
- else
177
- size <= 1 ? first : self
178
- end
179
- end
180
- def return_first(&block)
181
- returned = nil
182
- each { |item| break if (returned = block.call(item)) }
183
- returned
184
- end
185
- end
186
-
187
- module HashEx
188
-
189
- def ki(name)
190
- name.to_s[/(.*?)[?!=]?$/, 1]
191
- end
192
-
193
- def ki?(name)
194
- [name.sym, name.to_s, ki(name).sym, ki(name).to_s].any?{ |k| key?(k) }
195
- end
196
-
197
- def symvert(key_converter = :itself, value_converter = key_converter)
198
- each.with_object({}) do |(k,v),o|
199
- key = if key_converter.is_a?(Proc)
200
- key_converter.call(k, v)
201
- elsif k.respond_to?(key_converter.sym)
202
- k.__send__(key_converter.sym)
203
- else
204
- k
205
- end
206
-
207
- value = if value_converter.is_a?(Proc)
208
- value_converter.arity == 1 ? value_converter.call(v) : value_converter.call(k, v)
209
- elsif v.respond_to?(value_converter.sym)
210
- v.__send__(value_converter.sym)
211
- else
212
- v
213
- end
214
-
215
- o[key] = value
216
- end
217
- end
218
-
219
- def symvert!(key_converter = :itself, value_converter = key_converter)
220
- replace(symvert(key_converter, value_converter))
221
- end
222
-
223
- def method_missing(name, *args, &block)
224
- value = if name[-1] == '=' && args.size == 1
225
- key = name[0...-1].sym
226
- key = key.to_s if key?(key.to_s)
227
- self[key] = args.sequester
228
- elsif name[-1] == '?'
229
- key = name[0...-1].sym
230
- !!self[key, key.to_s]
231
- elsif name[-1] == '!'
232
- key = name[0...-1].sym
233
- val = self[key.sym] || self[key.to_s]
234
- if !val && (block || args.unempty?)
235
- self[key] = val = (block ? block.call(*args) : args.sequester)
236
- end
237
- super unless val
238
- else
239
- self[name.sym] || self[name.to_s]
240
- end
241
- value ||= args.sequester unless args.empty?
242
-
243
- return block ? block[value] : value
244
- end
245
- end
246
-
247
- class ::Hash
248
- include HashEx
249
-
250
- alias :mlookup :[]
251
- alias :mdef :default
252
- def [](*fkeys)
253
- fkeys.map { |key| mlookup(key) || fetch(key.sym) { fetch(key.to_s) { fetch(ki(key).sym) { fetch(ki(key).to_s) { mdef(key) }}}}}.sequester
254
- end
255
- end
256
-
257
- module MatchEx
258
- def to_hash
259
- Hash[ names.map(&:sym).zip( captures ) ]
260
- end
261
-
262
- def method_missing(name, *args, &block)
263
- if name[-1] == '?' && names.includes?(name[0...-1])
264
- return to_hash[name[0...-1].sym]
265
- elsif names.includes?(name.to_s)
266
- return to_hash[name.sym]
267
- end
268
- super
269
- end
270
- end
271
-
272
- class ::MatchData
273
- include MatchEx
274
- end
275
-
276
14
  class Token
277
15
  def initialize(type, *args)
278
16
  @type, @path, @options = type.to_sym, nil, {}
@@ -335,7 +73,7 @@ module Mobj
335
73
  if map.is_a?(Array)
336
74
  map << obj[key]
337
75
  else
338
- named = m.to_hash.invert
76
+ named = m.to_h.invert
339
77
  name = if named.empty?
340
78
  m.captures.empty? ? key : m.captures.sequester
341
79
  else
@@ -396,83 +134,6 @@ module Mobj
396
134
  end
397
135
  end
398
136
 
399
- class ::Symbol
400
- def walk(obj) to_s.walk(obj) end
401
- end
402
-
403
- class ::String
404
-
405
- def matches(regexp)
406
- start = 0
407
- matches = []
408
- while (match = match(regexp, start))
409
- start = match.end(0)
410
- matches << match
411
- yield match if block_given?
412
- end
413
- matches
414
- end
415
-
416
- def walk(obj) tokenize.walk(obj) end
417
-
418
- def tokenize
419
- tokens = []
420
-
421
- lit = /\~(?<literal>[^\.]+)/
422
- regex = /\/(?<regex>.*?(?<!\\))\//
423
- lookup = /\{\{(?<lookup>.*?)\}\}/
424
- up = /(?<up>\^)/
425
- path = /(?<path>[^\.\[]+)/
426
- indexes = /(?<indexes>[\d\+\.,\s-]+)/
427
-
428
- matcher = /#{lit}|#{regex}|#{lookup}|#{up}|#{path}(?:\[#{indexes}\])?/
429
-
430
- matches(matcher) do |match|
431
- if match.literal?
432
- tokens << Token.new(:literal, match.literal)
433
- elsif match.lookup?
434
- tokens << Token.new(:lookup, match.lookup.tokenize)
435
- elsif match.regex?
436
- tokens << Token.new(:regex, Regexp.new(match.regex))
437
- elsif match.up?
438
- tokens << Token.new(:up)
439
- elsif match.path?
440
- eachs = match.path.split(/\s*,\s*/)
441
- ors = match.path.split(/\s*\|\s*/)
442
- ands = match.path.split(/\s*\&\s*/)
443
- if eachs.size > 1
444
- tokens << Token.new(:each, eachs.map { |token| token.tokenize() })
445
- elsif ands.size > 1
446
- tokens << Token.new(:all, ands.map { |token| token.tokenize() })
447
- elsif ors.size > 1
448
- tokens << Token.new(:any, ors.map { |token| token.tokenize() })
449
- end
450
-
451
- unless ands.size + ors.size + eachs.size > 3
452
- options = {}
453
- index_matcher = /\s*(?<low>\d+)\s*(?:(?:\.\s*\.\s*(?<ex>\.)?\s*|-?)\s*(?<high>-?\d+|\+))?\s*/
454
-
455
- options[:indexes] = match.indexes.matches(index_matcher).map do |index|
456
- if index.high?
457
- Range.new(index.low.to_i, (index.high == "+" ? -1 : index.high.to_i), index.ex?)
458
- else
459
- index.low.to_i
460
- end
461
- end if match.indexes?
462
-
463
- if match.path[0] == '!'
464
- tokens << Token.new(:inverse, Token.new(:path, match.path[1..-1].sym, options))
465
- else
466
- tokens << Token.new(:path, match.path.sym, options)
467
- end
468
- end
469
- end
470
- end
471
-
472
- tokens.size == 1 ? tokens.first : Token.new(:root, tokens)
473
- end
474
- end
475
-
476
137
  class Circle
477
138
  def self.wrap(wrapped)
478
139
  return wrapped if wrapped.is_a?(CircleHash) || wrapped.is_a?(CircleRay)
@@ -531,5 +192,6 @@ module Mobj
531
192
  alias_method :lookup, :[]
532
193
  def [](*keys) keys.map { |key| self.lookup(key) }.sequester end
533
194
  end
195
+
534
196
  end
535
197
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mobj
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-15 00:00:00.000000000 Z
12
+ date: 2013-03-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -65,6 +65,17 @@ executables: []
65
65
  extensions: []
66
66
  extra_rdoc_files: []
67
67
  files:
68
+ - lib/ext/array.rb
69
+ - lib/ext/basic_object.rb
70
+ - lib/ext/class.rb
71
+ - lib/ext/fixnum.rb
72
+ - lib/ext/float.rb
73
+ - lib/ext/hash.rb
74
+ - lib/ext/match_data.rb
75
+ - lib/ext/nil.rb
76
+ - lib/ext/object.rb
77
+ - lib/ext/string.rb
78
+ - lib/ext/symbol.rb
68
79
  - lib/mobj.rb
69
80
  - README.md
70
81
  homepage: https://github.com/gnovos/mobj