mobj 1.6.8 → 1.6.9
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/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
|