mobj 2.2.1 → 2.4.0

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