mobj 1.6.8 → 1.6.9
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/mobj.rb +97 -78
- metadata +2 -2
data/lib/mobj.rb
CHANGED
@@ -1,42 +1,5 @@
|
|
1
1
|
module Mobj
|
2
2
|
|
3
|
-
|
4
|
-
#magic init
|
5
|
-
#class Object
|
6
|
-
# alias_method :orig_method_missing, :method_missing
|
7
|
-
#
|
8
|
-
# def method_missing(m, *a, &b)
|
9
|
-
# klass = begin
|
10
|
-
# (self.is_a?(Module) ? self : self.class).const_get(m)
|
11
|
-
# rescue NameError
|
12
|
-
# end
|
13
|
-
#
|
14
|
-
# return klass.send(:parens, *a, &b) if klass.respond_to? :parens
|
15
|
-
# orig_method_missing m, *a, &b
|
16
|
-
# end
|
17
|
-
#end
|
18
|
-
|
19
|
-
#class Object
|
20
|
-
# alias_method :orig_method_missing, :method_missing
|
21
|
-
#
|
22
|
-
# def method_missing(m, *a, &b)
|
23
|
-
# begin
|
24
|
-
# l = eval(m.to_s, binding_n(1))
|
25
|
-
# rescue NameError
|
26
|
-
# else
|
27
|
-
# return l.call(*a) if l.respond_to? :call
|
28
|
-
# end
|
29
|
-
# orig_method_missing m, *a, &b
|
30
|
-
# end
|
31
|
-
#end
|
32
|
-
#
|
33
|
-
#def call_a_lambda_with_parenths(val)
|
34
|
-
# l = lambda {|v| p v }
|
35
|
-
# l(val)
|
36
|
-
#end
|
37
|
-
#
|
38
|
-
#call_a_lambda_with_parenths(6)
|
39
|
-
|
40
3
|
class ::BasicObject
|
41
4
|
def class
|
42
5
|
klass = class << self; self end
|
@@ -65,15 +28,14 @@ module Mobj
|
|
65
28
|
class ::Object
|
66
29
|
alias responds_to? respond_to?
|
67
30
|
def sym() respond_to?(:to_sym) ? to_sym : to_s.to_sym end
|
68
|
-
def
|
69
|
-
def
|
70
|
-
def
|
71
|
-
def
|
72
|
-
|
73
|
-
|
74
|
-
@mparent = rent == self ? nil : rent
|
31
|
+
def __mobj__root() __mobj__parent.nil? || __mobj__parent == self ? self : __mobj__parent.__mobj__root end
|
32
|
+
def __mobj__reparent() values.each { |v| v.__mobj__parent(self); v.__mobj__reparent } if respond_to? :values end
|
33
|
+
def __mobj__parent?() !@__mobj__parent.nil? end
|
34
|
+
def __mobj__parent(rent = :"__mobj__parent")
|
35
|
+
unless rent == :"__mobj__parent"
|
36
|
+
@__mobj__parent = rent == self ? nil : rent
|
75
37
|
end
|
76
|
-
@
|
38
|
+
@__mobj__parent
|
77
39
|
end
|
78
40
|
def attempt(value=:root)
|
79
41
|
Forwarder.new do |name, *args, &block|
|
@@ -88,19 +50,25 @@ module Mobj
|
|
88
50
|
end
|
89
51
|
end
|
90
52
|
end
|
91
|
-
alias_method :try
|
53
|
+
alias_method :try!, :attempt
|
92
54
|
alias_method :do?, :attempt
|
93
55
|
alias_method :does?, :attempt
|
94
56
|
alias_method :if!, :attempt
|
95
57
|
|
58
|
+
def try?()
|
59
|
+
Forwarder.new do |name, *args, &block|
|
60
|
+
methods(true).include?(name) ? __send__(name, *args, &block) : nil.null!
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
96
64
|
def when
|
97
65
|
Forwarder.new do |name, *args, &block|
|
98
|
-
if
|
66
|
+
if methods.include?(name) && __send__(name, *args, &block)
|
99
67
|
thn = Forwarder.new do |name, *args, &block|
|
100
68
|
if name.sym == :then
|
101
69
|
thn
|
102
70
|
else
|
103
|
-
ret =
|
71
|
+
ret = __send__(name, *args, &block)
|
104
72
|
ret.define_singleton_method(:else) { Forwarder.new { ret } }
|
105
73
|
ret
|
106
74
|
end
|
@@ -110,7 +78,7 @@ module Mobj
|
|
110
78
|
if name.sym == :then
|
111
79
|
els = Forwarder.new do |name|
|
112
80
|
if name.sym == :else
|
113
|
-
Forwarder.new { |name, *args, &block|
|
81
|
+
Forwarder.new { |name, *args, &block| __send__(name, *args, &block) }
|
114
82
|
else
|
115
83
|
els
|
116
84
|
end
|
@@ -126,6 +94,37 @@ module Mobj
|
|
126
94
|
end
|
127
95
|
|
128
96
|
class ::NilClass
|
97
|
+
MOBJ_NULL_REGION_BEGIN = __LINE__
|
98
|
+
def __mobj__caller()
|
99
|
+
caller.find do |frame|
|
100
|
+
(file, line) = frame.split(":")
|
101
|
+
file != __FILE__ || !(MOBJ_NULL_REGION_BEGIN..MOBJ_NULL_REGION_END).cover?(line.to_i)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
def null?()
|
105
|
+
@@null ||= nil
|
106
|
+
@@null && @@null == __mobj__caller
|
107
|
+
end
|
108
|
+
def null!()
|
109
|
+
@@null = __mobj__caller
|
110
|
+
self
|
111
|
+
end
|
112
|
+
def nil!
|
113
|
+
@@null = nil
|
114
|
+
self
|
115
|
+
end
|
116
|
+
def method_missing(name, *args, &block)
|
117
|
+
if null?
|
118
|
+
self
|
119
|
+
else
|
120
|
+
nil!
|
121
|
+
super
|
122
|
+
end
|
123
|
+
end
|
124
|
+
alias_method :try?, :null!
|
125
|
+
|
126
|
+
MOBJ_NULL_REGION_END = __LINE__
|
127
|
+
|
129
128
|
def attempt(value=true)
|
130
129
|
Forwarder.new do |name, *args, &block|
|
131
130
|
if self.methods(true).include? name
|
@@ -139,7 +138,7 @@ module Mobj
|
|
139
138
|
end
|
140
139
|
end
|
141
140
|
end
|
142
|
-
alias_method :try
|
141
|
+
alias_method :try!, :attempt
|
143
142
|
alias_method :do?, :attempt
|
144
143
|
alias_method :does?, :attempt
|
145
144
|
alias_method :if!, :attempt
|
@@ -174,7 +173,7 @@ module Mobj
|
|
174
173
|
def method_missing(name, *args, &block)
|
175
174
|
if name[-1] == '=' && args.size == 1
|
176
175
|
key = name[0...-1].sym
|
177
|
-
key = key.
|
176
|
+
key = key.to_s if key?(key.to_s)
|
178
177
|
return self[key] = args.sequester
|
179
178
|
elsif name[-1] == '?'
|
180
179
|
key = name[0...-1].sym
|
@@ -234,7 +233,7 @@ module Mobj
|
|
234
233
|
def to_s() "#{@type.to_s.upcase}(#@path#{ " => #@options" unless @options.empty?})" end
|
235
234
|
|
236
235
|
def extract(obj, path)
|
237
|
-
obj.
|
236
|
+
obj.__mobj__reparent
|
238
237
|
if path == :* || obj.nil?
|
239
238
|
obj
|
240
239
|
elsif obj.is_a?(Array)
|
@@ -265,9 +264,9 @@ module Mobj
|
|
265
264
|
obj.keys.map { |key| key if key.match(@path) }.compact.map{|key| obj[key] }
|
266
265
|
when :up
|
267
266
|
if obj.respond_to? :parent
|
268
|
-
obj.
|
267
|
+
obj.__mobj__parent || obj.__mobj__parent
|
269
268
|
else
|
270
|
-
obj.
|
269
|
+
obj.__mobj__parent
|
271
270
|
end
|
272
271
|
when :any
|
273
272
|
@path.return_first { |token| token.walk(obj, root) }
|
@@ -300,12 +299,15 @@ module Mobj
|
|
300
299
|
|
301
300
|
class ::String
|
302
301
|
|
303
|
-
def matches(regexp
|
302
|
+
def matches(regexp)
|
304
303
|
start = 0
|
304
|
+
matches = []
|
305
305
|
while (match = match(regexp, start))
|
306
306
|
start = match.end(0)
|
307
|
-
|
307
|
+
matches << match
|
308
|
+
yield match if block_given?
|
308
309
|
end
|
310
|
+
matches
|
309
311
|
end
|
310
312
|
|
311
313
|
def walk(obj)
|
@@ -314,19 +316,29 @@ module Mobj
|
|
314
316
|
|
315
317
|
def tokenize
|
316
318
|
tokens = []
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
319
|
+
|
320
|
+
lit = /\~(?<literal>[^\.]+)/
|
321
|
+
regex = /\/(?<regex>.*?(?<!\\))\//
|
322
|
+
lookup = /\{\{(?<lookup>.*?)\}\}/
|
323
|
+
up = /(?<up>\^)/
|
324
|
+
path = /(?<path>[^\.\[]+)/
|
325
|
+
indexes = /(?<indexes>[\d\+\.,-]+)/
|
326
|
+
|
327
|
+
matcher = /#{lit}|#{regex}|#{lookup}|#{up}|#{path}(?:\[#{indexes}\])?/
|
328
|
+
|
329
|
+
matches(matcher) do |match|
|
330
|
+
if match.literal?
|
331
|
+
tokens << Token.new(:literal, match.literal)
|
332
|
+
elsif match.lookup?
|
333
|
+
tokens << Token.new(:lookup, match.lookup.tokenize)
|
334
|
+
elsif match.regex?
|
335
|
+
tokens << Token.new(:regex, Regexp.new(match.regex))
|
336
|
+
elsif match.up?
|
325
337
|
tokens << Token.new(:up)
|
326
|
-
elsif path
|
327
|
-
eachs = path.split(",")
|
328
|
-
ors = path.split("|")
|
329
|
-
ands = path.split("&")
|
338
|
+
elsif match.path?
|
339
|
+
eachs = match.path.split(",")
|
340
|
+
ors = match.path.split("|")
|
341
|
+
ands = match.path.split("&")
|
330
342
|
if eachs.size > 1
|
331
343
|
tokens << Token.new(:each, eachs.map { |token| token.tokenize() })
|
332
344
|
elsif ands.size > 1
|
@@ -337,19 +349,26 @@ module Mobj
|
|
337
349
|
|
338
350
|
unless ands.size + ors.size + eachs.size > 3
|
339
351
|
options = {}
|
340
|
-
|
341
|
-
len.nil? ? start.to_i : (Range.new(start.to_i, (len == "+" ? -1 : len.to_i), !exc.nil?))
|
342
|
-
end if indexes
|
352
|
+
index_matcher = /(?<low>\d+)(?:(?:\.\.(?<ex>\.)?|-?)(?<high>-?\d+|\+))?/
|
343
353
|
|
344
|
-
|
345
|
-
|
354
|
+
options[:indexes] = match.indexes.matches(index_matcher).map do |index|
|
355
|
+
if index.high?
|
356
|
+
Range.new(index.low.to_i, (index.high == "+" ? -1 : index.high.to_i), index.ex?)
|
357
|
+
else
|
358
|
+
index.low.to_i
|
359
|
+
end
|
360
|
+
end if match.indexes?
|
361
|
+
|
362
|
+
if match.path[0] == '!'
|
363
|
+
tokens << Token.new(:inverse, Token.new(:path, match.path[1..-1].sym, options))
|
346
364
|
else
|
347
|
-
tokens << Token.new(:path, path.sym, options)
|
365
|
+
tokens << Token.new(:path, match.path.sym, options)
|
348
366
|
end
|
349
367
|
end
|
350
368
|
end
|
351
369
|
end
|
352
|
-
|
370
|
+
|
371
|
+
tokens.size == 1 ? tokens.first : Token.new(:root, tokens)
|
353
372
|
end
|
354
373
|
end
|
355
374
|
|
@@ -385,7 +404,7 @@ module Mobj
|
|
385
404
|
end
|
386
405
|
|
387
406
|
def []=(*keys, val)
|
388
|
-
val.
|
407
|
+
val.__mobj__parent(self)
|
389
408
|
keys.each { |key| store(key.sym, val) }
|
390
409
|
end
|
391
410
|
end
|
@@ -395,14 +414,14 @@ module Mobj
|
|
395
414
|
|
396
415
|
alias_method :set, :[]=
|
397
416
|
def []=(*keys, val)
|
398
|
-
val.
|
417
|
+
val.__mobj__parent(self)
|
399
418
|
set(*keys, val)
|
400
419
|
end
|
401
420
|
|
402
421
|
alias_method :append, :<<
|
403
422
|
def <<(*vals)
|
404
423
|
vals.each do |val|
|
405
|
-
val.
|
424
|
+
val.__mobj__parent(self)
|
406
425
|
self.append(val)
|
407
426
|
end
|
408
427
|
self
|
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: 1.6.
|
4
|
+
version: 1.6.9
|
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: 2012-11-
|
12
|
+
date: 2012-11-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|