mobj 1.0.0 → 1.5.4

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.
Files changed (3) hide show
  1. data/README.md +4 -59
  2. data/lib/mobj.rb +99 -58
  3. metadata +2 -2
data/README.md CHANGED
@@ -1,71 +1,16 @@
1
- ctx
1
+ mobj
2
2
  ===
3
3
 
4
- Simple utility to limit method redefinition within the bounds of arbitrary logical scopes
4
+ Some utilities that I keep using.
5
5
 
6
6
  Example
7
7
  ===
8
8
 
9
- Here, figure it out:
10
-
11
- require 'ctx'
12
-
13
- class ::String
14
- ctx :reversaroo do
15
- def +(other)
16
- "#{other.reverse}#{self.reverse}"
17
- end
18
- end
19
- ctx :camels do
20
- def +(other)
21
- "#{self.capitalize}#{other.capitalize}"
22
- end
23
- end
24
- ctx :polite do
25
- def +(other)
26
- "I say, good day to you there '#{other}', may I introduce you to my good friend '#{self}'?"
27
- end
28
- end
29
- ctx do
30
- def +(other)
31
- "#{self} + #{other} = ?"
32
- end
33
- end
34
- end
35
-
36
- puts "hello" + "world"
37
- #=> helloworld
38
-
39
- ctx :camels do
40
- puts "hello" + "world"
41
- #=> HelloWorld
42
-
43
- ctx :polite do
44
- puts "hello" + "world"
45
- #=> I say, good day to you there 'world', may I introduce you to my good friend 'hello'?
46
- end
47
-
48
- ctx do
49
- puts "hello" + "world"
50
- #=> hello + world = ?
51
- end
52
- end
53
-
54
- ctx :reversaroo do
55
- puts "hello" + "world"
56
- #=> dlrowolleh
57
- end
58
-
59
- puts "hello" + "world"
60
- #=> helloworld
61
-
62
-
63
- There are bugs. You'll find them.
9
+ Read the code.
64
10
 
65
11
  ---
66
12
 
67
13
  Caveats and such
68
14
  ===
69
15
 
70
- For whatever goofy reason, this stuff doesn't play well with rspec all the time, particularly if you override stuff the matchers are hoping to also override, like == or =~ on String, or whatnot. Don't do that right now unless you like stuff to break in inexplicable ways. Personally, I do like that kind of stuff, makes life interesting (kind of explains my dating choices, when you get right down to it), but anywhoo, honestly, it's your call.
71
-
16
+ None. It's prefection.
data/lib/mobj.rb CHANGED
@@ -1,18 +1,29 @@
1
1
  module Mobj
2
2
 
3
- class ::BasicObject
3
+ class ::Object
4
+ alias responds_to? respond_to?
4
5
  def sym() respond_to?(:to_sym) ? to_sym : to_s.to_sym end
5
- def mparent(rent = :mparent) @mparent = rent unless rent == :mparent; @mparent end
6
- def mroot() mparent.nil? ? self : mparent.mroot end
6
+ def mroot() mparent.nil? || mparent == self ? self : mparent.mroot end
7
+ def reparent() values.each { |v| v.mparent(self); v.reparent } if respond_to? :values end
8
+ def mparent(rent = :mparent)
9
+ unless rent == :mparent
10
+ @mparent = rent == self ? nil : rent
11
+ end
12
+ @mparent
13
+ end
7
14
  end
8
15
 
9
16
  class ::Class
10
- def object_methods() (self.instance_methods - Object.instance_methods).sort end
11
- def class_methods() (self.singleton_methods - Object.singleton_methods).sort end
17
+ def object_methods() (self.instance_methods(true) - Object.instance_methods(true)).sort end
18
+ def class_methods() (self.singleton_methods(true) - Object.singleton_methods(true)).sort end
12
19
  def defined_methods() (class_methods | object_methods).sort end
13
20
  end
14
21
 
15
22
  class ::Array
23
+ alias includes? include?
24
+ alias contains? include?
25
+
26
+ def values() self end
16
27
  def sequester(lim = 1) compact.size <= lim ? compact.first : self end
17
28
  def return_first(&block)
18
29
  returned = nil
@@ -21,7 +32,7 @@ module Mobj
21
32
  end
22
33
  end
23
34
 
24
- class Moken
35
+ class Token
25
36
  def initialize(type, *args)
26
37
  @type, @path, @options = type.to_sym, nil, {}
27
38
  tokens = []
@@ -40,29 +51,33 @@ module Mobj
40
51
  def to_s() "#{@type.to_s.upcase}(#@path#{ " => #@options" unless @options.empty?})" end
41
52
 
42
53
  def extract(obj, path)
43
- if obj.is_a?(Array)
44
- if path == :*
45
- obj
46
- else
47
- obj.map { |o| extract(o, path)}
48
- end
54
+ obj.reparent
55
+ if path == :*
56
+ obj
57
+ elsif obj.is_a?(Array)
58
+ obj.map { |o| extract(o, path) }
59
+ elsif path.is_a?(Array)
60
+ path.map { |pth| obj[pth.sym] }
49
61
  else
50
- if path.is_a?(Array)
51
- path.map { |pth| obj[pth.sym] }
52
- else
53
- obj[path.sym]
54
- end
62
+ obj[path.sym]
55
63
  end
56
64
  end
57
65
 
58
66
  def walk(obj, root = obj)
67
+ obj, root = Circle.wrap(obj), Circle.wrap(root)
59
68
  val = case @type
60
69
  when :literal
61
70
  @path.to_s
62
71
  when :path
63
72
  extract(obj, @path)
64
73
  when :regex
65
- obj.keys.map { |key| key if key.match(@path) }.compact.map{|key| obj[key]}
74
+ obj.keys.map { |key| key if key.match(@path) }.compact.map{|key| obj[key] }
75
+ when :up
76
+ if obj.respond_to? :parent
77
+ obj.mparent || obj.parent
78
+ else
79
+ obj.mparent
80
+ end
66
81
  when :any
67
82
  @path.return_first { |token| token.walk(obj, root) }
68
83
  when :all
@@ -78,7 +93,7 @@ module Mobj
78
93
  lookup.tokenize.walk(root)
79
94
  end
80
95
  when :inverse
81
- raise "not implemented yet. not sure how to implement yet, actually. please continue to hold. your call is important to us."
96
+ raise "not implemented yet. not sure how to implement yet, actually. please continue to hold. your call is important to us."
82
97
  when :root
83
98
  tree = [@path].flatten
84
99
  while (path = tree.shift)
@@ -87,7 +102,8 @@ module Mobj
87
102
  obj.is_a?(Array) ? obj.flatten : obj
88
103
  end
89
104
 
90
- @options[:indexes] ? val.values_at(*@options[:indexes]) : val
105
+ val = @options[:indexes] ? val.values_at(*@options[:indexes]) : val
106
+ val
91
107
  end
92
108
  end
93
109
 
@@ -96,23 +112,25 @@ module Mobj
96
112
 
97
113
  def tokenize
98
114
  tokens = []
99
- scan(/\~([^\.]+)|\/(.*?)\/|\{\{(.*?)\}\}|([^\.\[]+)(?:\[([\d\+\.,-]+)\])?/).each do |literal, regex, lookup, path, indexes|
115
+ scan(/\~([^\.]+)|\/(.*?)\/|\{\{(.*?)\}\}|(\^)|([^\.\[]+)(?:\[([\d\+\.,-]+)\])?/).each do |literal, regex, lookup, up, path, indexes|
100
116
  if literal
101
- tokens << Moken.new(:literal, literal)
117
+ tokens << Token.new(:literal, literal)
102
118
  elsif lookup
103
- tokens << Moken.new(:lookup, lookup.tokenize)
119
+ tokens << Token.new(:lookup, lookup.tokenize)
104
120
  elsif regex
105
- tokens << Moken.new(:regex, Regexp.new(regex))
121
+ tokens << Token.new(:regex, Regexp.new(regex))
122
+ elsif up
123
+ tokens << Token.new(:up)
106
124
  elsif path
107
125
  eachs = path.split(",")
108
126
  ors = path.split("|")
109
127
  ands = path.split("&")
110
128
  if eachs.size > 1
111
- tokens << Moken.new(:each, eachs.map { |token| token.tokenize() })
129
+ tokens << Token.new(:each, eachs.map { |token| token.tokenize() })
112
130
  elsif ands.size > 1
113
- tokens << Moken.new(:all, ands.map { |token| token.tokenize() })
131
+ tokens << Token.new(:all, ands.map { |token| token.tokenize() })
114
132
  elsif ors.size > 1
115
- tokens << Moken.new(:any, ors.map { |token| token.tokenize() })
133
+ tokens << Token.new(:any, ors.map { |token| token.tokenize() })
116
134
  end
117
135
 
118
136
  unless ands.size + ors.size + eachs.size > 3
@@ -122,59 +140,82 @@ module Mobj
122
140
  end if indexes
123
141
 
124
142
  if path[0] == '!'
125
- tokens << Moken.new(:inverse, Moken.new(:path, path[1..-1].sym, options))
143
+ tokens << Token.new(:inverse, Token.new(:path, path[1..-1].sym, options))
126
144
  else
127
- tokens << Moken.new(:path, path.sym, options)
145
+ tokens << Token.new(:path, path.sym, options)
128
146
  end
129
147
  end
130
148
  end
131
149
  end
132
- tokens.size == 1 ? tokens.first : Moken.new(:root, tokens)
150
+ tokens.size == 1 ? tokens.first : Token.new(:root, tokens)
133
151
  end
134
152
  end
135
153
 
136
- class Circle < Hash
154
+ class Circle
155
+ def self.wrap(wrapped)
156
+ return wrapped if wrapped.is_a?(CircleHash) || wrapped.is_a?(CircleRay)
137
157
 
138
- def initialize
139
- super
140
- @index = 0
158
+ if wrapped.is_a?(Array)
159
+ circle = CircleRay.new
160
+ wrapped.each_with_index { |item, i| circle[i] = wrap(item) }
161
+ circle
162
+ elsif wrapped.is_a?(Hash)
163
+ circle = CircleHash.new
164
+ wrapped.each_pair { |key, val| circle[key] = wrap(val) }
165
+ circle
166
+ else
167
+ wrapped
168
+ end
141
169
  end
170
+ end
142
171
 
143
- def <<(val)
144
- self[@index] = val
145
- @index += 1
172
+ class CircleHash < Hash
173
+ def *(&block)
174
+ if block.nil?
175
+ self
176
+ else
177
+ map = CircleHash.new
178
+ self.each_pair do |key, val|
179
+ map.merge!(block.call(key, val))
180
+ end
181
+ map
182
+ end
146
183
  end
147
184
 
148
185
  def []=(*keys, val)
149
186
  val.mparent(self)
150
- keys.each do |key|
151
- if key.is_a?(Range)
152
- key.to_a.each{ |k| self[k]= val }
153
- else
154
- @index = key + 1 if key.is_a?(Fixnum) && key >= @index
155
- store(key.sym, val)
156
- end
157
- end
187
+ keys.each { |key| store(key.sym, val) }
158
188
  end
159
189
 
160
190
  alias_method :lookup, :[]
161
- def [](*keys) keys.map { |key| self.lookup(key.sym) }.sequester
162
- end
191
+ def [](*keys) keys.map { |key| self.lookup(key.sym) }.sequester end
163
192
 
164
- def method_missing(name, *args, &block)
165
- self.has_key?(name) ? self[name] : super(name, *args, &block)
193
+ def method_missing(name, *args, &block) self.has_key?(name) ? self[name] : super(name, *args, &block) end
194
+ end
195
+
196
+ class CircleRay < Array
197
+ alias_method :*, :map
198
+
199
+ alias_method :set, :[]=
200
+ def []=(*keys, val)
201
+ val.mparent(self)
202
+ set(*keys, val)
166
203
  end
167
204
 
168
- def self.wrap(wrapped)
169
- circle = self.new
170
- if wrapped.is_a?(Array)
171
- wrapped.each_with_index { |item, i| circle[i] = wrap(item) }
172
- elsif wrapped.is_a?(Hash)
173
- wrapped.each_pair { |key, val| circle[key] = wrap(val) }
174
- else
175
- return wrapped
205
+ alias_method :append, :<<
206
+ def <<(*vals)
207
+ vals.each do |val|
208
+ val.mparent(self)
209
+ self.append(val)
176
210
  end
177
- circle
211
+ self
212
+ end
213
+
214
+ alias_method :lookup, :[]
215
+ def [](*keys)
216
+ keys.map do |key|
217
+ self.lookup(key)
218
+ end.sequester
178
219
  end
179
220
  end
180
221
 
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.0.0
4
+ version: 1.5.4
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-10 00:00:00.000000000 Z
12
+ date: 2012-11-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec