utilrb 2.0.2.b2 → 2.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.boring +40 -0
  3. data/.gitignore +13 -0
  4. data/.travis.yml +5 -0
  5. data/CMakeLists.txt +18 -0
  6. data/Gemfile +3 -0
  7. data/Makefile +8 -0
  8. data/Manifest.txt +0 -8
  9. data/{README.rd → README.md} +11 -7
  10. data/Rakefile +16 -63
  11. data/benchmarks/validate_options.rb +79 -0
  12. data/ext/utilrb/extconf.rb +1 -17
  13. data/ext/utilrb/utilrb.cc +0 -23
  14. data/lib/utilrb/column_formatter.rb +8 -5
  15. data/lib/utilrb/common.rb +1 -6
  16. data/lib/utilrb/enumerable/uniq.rb +2 -8
  17. data/lib/utilrb/event_loop.rb +5 -10
  18. data/lib/utilrb/kernel/load_dsl_file.rb +1 -2
  19. data/lib/utilrb/kernel/options.rb +25 -29
  20. data/lib/utilrb/logger/hierarchy.rb +0 -1
  21. data/lib/utilrb/logger/io.rb +3 -3
  22. data/lib/utilrb/logger/root.rb +12 -6
  23. data/lib/utilrb/module/ancestor_p.rb +0 -12
  24. data/lib/utilrb/module/is_singleton.rb +6 -0
  25. data/lib/utilrb/module/singleton_class_p.rb +14 -0
  26. data/lib/utilrb/object/attribute.rb +33 -65
  27. data/lib/utilrb/object/singleton_class.rb +1 -20
  28. data/lib/utilrb/pkgconfig.rb +21 -10
  29. data/lib/utilrb/socket/tcp_server.rb +2 -2
  30. data/lib/utilrb/spawn.rb +1 -1
  31. data/lib/utilrb/test.rb +65 -0
  32. data/lib/utilrb/thread_pool.rb +11 -13
  33. data/lib/utilrb/timepoints.rb +15 -0
  34. data/lib/utilrb/value_set.rb +10 -1
  35. data/lib/utilrb/version.rb +4 -0
  36. data/lib/utilrb/weakref.rb +11 -12
  37. data/lib/utilrb/yard.rb +0 -111
  38. data/lib/utilrb.rb +6 -1
  39. data/lib/yard-utilrb.rb +1 -0
  40. data/manifest.xml +19 -0
  41. data/package.xml +29 -0
  42. data/utilrb.gemspec +27 -0
  43. metadata +56 -107
  44. data/ext/utilrb/proc.c +0 -39
  45. data/ext/utilrb/readline.c +0 -52
  46. data/ext/utilrb/weakref.cc +0 -143
  47. data/lib/utilrb/models/inherited_enumerable.rb +0 -341
  48. data/lib/utilrb/models/registration.rb +0 -115
  49. data/lib/utilrb/module/inherited_enumerable.rb +0 -6
  50. data/lib/utilrb/objectstats.rb +0 -193
  51. data/lib/utilrb/ruby_object_graph.rb +0 -384
  52. data/test/data/test_pkgconfig.pc +0 -9
  53. data/test/data/test_pkgconfig_empty.pc +0 -10
  54. data/test/test_array.rb +0 -15
  55. data/test/test_config.rb +0 -4
  56. data/test/test_dir.rb +0 -22
  57. data/test/test_enumerable.rb +0 -119
  58. data/test/test_event_loop.rb +0 -407
  59. data/test/test_exception.rb +0 -38
  60. data/test/test_gc.rb +0 -34
  61. data/test/test_hash.rb +0 -102
  62. data/test/test_kernel.rb +0 -300
  63. data/test/test_logger.rb +0 -204
  64. data/test/test_misc.rb +0 -42
  65. data/test/test_models.rb +0 -212
  66. data/test/test_module.rb +0 -126
  67. data/test/test_object.rb +0 -77
  68. data/test/test_objectstats.rb +0 -26
  69. data/test/test_pkgconfig.rb +0 -84
  70. data/test/test_proc.rb +0 -31
  71. data/test/test_set.rb +0 -19
  72. data/test/test_thread_pool.rb +0 -409
  73. data/test/test_time.rb +0 -47
  74. data/test/test_unbound_method.rb +0 -23
  75. data/test/test_weakref.rb +0 -81
@@ -1,384 +0,0 @@
1
- require 'stringio'
2
- require 'utilrb/value_set'
3
- require 'utilrb/kernel/options'
4
- module Utilrb
5
- begin
6
- require 'roby/graph'
7
- has_roby_graph = true
8
- rescue LoadError
9
- has_roby_graph = false
10
- end
11
-
12
- if has_roby_graph
13
- class RubyObjectGraph
14
- module GraphGenerationObjectMaker
15
- def __ruby_object_graph_internal__; end
16
- end
17
- attr_reader :graph
18
- attr_reader :references
19
-
20
- # Takes a snapshot of all objects currently live
21
- def self.snapshot
22
- # Doing any Ruby code that do not modify the heap is impossible. List
23
- # all existing objects once, and only then do the processing.
24
- # +live_objects+ will be referenced in itself, but we are going to
25
- # remove it later
26
- GC.disable
27
- live_objects = Array.new
28
- ObjectSpace.each_object do |obj|
29
- if obj.object_id != live_objects.object_id
30
- live_objects << obj
31
- end
32
- end
33
- GC.enable
34
- live_objects
35
- end
36
-
37
- # Generates a graph of all the objects currently live, in dot format
38
- def self.dot_snapshot(options = Hash.new)
39
- r, w = IO.pipe
40
- live_objects = RubyObjectGraph.snapshot
41
- fork do
42
- options, register_options = Kernel.filter_options options,
43
- :collapse => nil
44
- ruby_graph = RubyObjectGraph.new
45
- ruby_graph.register_references_to(live_objects, register_options)
46
- if options[:collapse]
47
- ruby_graph.collapse(*options[:collapse])
48
- end
49
- w.write ruby_graph.to_dot
50
- exit! true
51
- end
52
- w.close
53
- r.read
54
- end
55
-
56
- def initialize
57
- @graph = BGL::Graph.new
58
- @references = Hash.new
59
- end
60
-
61
- def clear
62
- graph.each_edge do |from, to, info|
63
- info.clear
64
- end
65
- graph.clear
66
- references.clear
67
- end
68
-
69
- # This class is used to store any ruby object into a BGL::Graph (i.e.
70
- # the live graph)
71
- class ObjectRef
72
- # The referenced object
73
- attr_reader :obj
74
-
75
- def __ruby_object_graph_internal__; end
76
-
77
- def initialize(obj)
78
- @obj = obj
79
- end
80
- include BGL::Vertex
81
- end
82
-
83
- def test_and_add_reference(obj_ref, var, desc)
84
- var_ref = references[var.object_id]
85
- if graph.include?(var_ref)
86
- add_reference(obj_ref, var_ref, desc)
87
- end
88
- end
89
-
90
- # Register a ruby object reference
91
- #
92
- # @param [ObjectRef] obj_ref the object that is referencing
93
- # @param [ObjectRef] var_ref the object that is referenced
94
- # @param desc the description for the link. For instance, if obj_ref
95
- # references var_ref because of an instance variable, this is going to
96
- # be the name of the instance variable
97
- # @return [void]
98
- def add_reference(obj_ref, var_ref, desc)
99
- if graph.linked?(obj_ref, var_ref)
100
- desc_set = obj_ref[var_ref, graph]
101
- if !desc_set.include?(desc)
102
- desc_set << desc
103
- end
104
- else
105
- desc_set = [desc]
106
- graph.link(obj_ref, var_ref, desc_set)
107
- end
108
- end
109
-
110
- # Creates a BGL::Graph of ObjectRef objects which stores the current
111
- # ruby object graph
112
- #
113
- # @param [Class] klass seed
114
- # @option options [Array<Object>] roots (nil) if given, the list of root
115
- # objects. Objects that are not referenced by one of these roots will
116
- # not be included in the final graph
117
- def register_references_to(live_objects, options = Hash.new)
118
- orig_options = options # to exclude it from the graph
119
- options = Kernel.validate_options options,
120
- :roots => [Object], :excluded_classes => [], :excluded_objects => [],
121
- :include_class_relation => false
122
- roots_class, roots = options[:roots].partition { |obj| obj.kind_of?(Class) }
123
- excluded_classes = options[:excluded_classes]
124
- excluded_objects = options[:excluded_objects]
125
- include_class_relation = options[:include_class_relation]
126
-
127
- # Create a single ObjectRef per (interesting) live object, so that we
128
- # can use a BGL::Graph to represent the reference graph. This will be
129
- # what we are going to access later on. Use object IDs since we really
130
- # want to refer to objects and not use eql? comparisons
131
- desired_seeds = roots.map(&:object_id)
132
- excludes = [live_objects, self, graph, references, orig_options, options, roots, roots_class].to_value_set
133
- live_objects_total = live_objects.size
134
- live_objects.delete_if do |obj|
135
- if obj.kind_of?(DRbObject)
136
- true
137
- elsif excludes.include?(obj) || obj.respond_to?(:__ruby_object_graph_internal__)
138
- true
139
- else
140
- references[obj.object_id] ||= ObjectRef.new(obj)
141
- if roots_class.any? { |k| obj.kind_of?(k) }
142
- if !excluded_classes.any? { |k| obj.kind_of?(k) }
143
- if !excluded_objects.include?(obj)
144
- desired_seeds << obj.object_id
145
- end
146
- end
147
- end
148
- false
149
- end
150
- end
151
-
152
- desired_seeds.each do |obj_id|
153
- graph.insert(references[obj_id])
154
- end
155
- ignored_enumeration = Hash.new
156
-
157
- names = Hash[
158
- :array => "Array",
159
- :value_set => "ValueSet[]",
160
- :vertex => "Vertex[]",
161
- :edge => "Edge[]",
162
- :hash_key => "Hash[key]",
163
- :hash_value => "Hash[value]",
164
- :proc => "Proc",
165
- :ancestor => "Ancestor"]
166
- puts "RubyObjectGraph: #{live_objects.size} objects found, #{desired_seeds.size} seeds and #{live_objects_total} total live objects"
167
- loop do
168
- old_graph_size = graph.size
169
- live_objects.each do |obj|
170
- obj_ref = references[obj.object_id]
171
-
172
- if include_class_relation
173
- test_and_add_reference(obj_ref, obj.class, "class")
174
- end
175
-
176
- for var_name in obj.instance_variables
177
- var = obj.instance_variable_get(var_name)
178
- test_and_add_reference(obj_ref, var, var_name.to_s)
179
- end
180
-
181
- case obj
182
- when Array
183
- for var in obj
184
- test_and_add_reference(obj_ref, var, names[:array])
185
- end
186
- when ValueSet
187
- for var in obj
188
- test_and_add_reference(obj_ref, var, names[:value_set])
189
- end
190
- when BGL::Graph
191
- obj.each_vertex do
192
- test_and_add_reference(obj_ref, var, names[:vertex])
193
- end
194
- obj.each_edge do |_, _, info|
195
- test_and_add_reference(obj_ref, info, names[:edge])
196
- end
197
- when Hash
198
- for var in obj
199
- test_and_add_reference(obj_ref, var[0], names[:hash_key])
200
- test_and_add_reference(obj_ref, var[1], names[:hash_value])
201
- end
202
- when Proc
203
- if obj.respond_to?(:references)
204
- for var in obj.references
205
- begin
206
- test_and_add_reference(obj_ref, ObjectSpace._id2ref(var), names[:proc])
207
- rescue RangeError
208
- end
209
- end
210
- end
211
- when Class
212
- for ref in obj.ancestors
213
- test_and_add_reference(obj_ref, ref, names[:ancestor])
214
- end
215
- else
216
- if obj.respond_to?(:each)
217
- if obj.kind_of?(Module) || obj.kind_of?(Class)
218
- if !ignored_enumeration[obj]
219
- ignored_enumeration[obj] = true
220
- puts "ignoring enumerator class/module #{obj}"
221
- end
222
- else
223
- if !ignored_enumeration[obj.class]
224
- ignored_enumeration[obj.class] = true
225
- puts "ignoring enumerator object of class #{obj.class}"
226
- end
227
- end
228
- end
229
- end
230
- end
231
- if old_graph_size == graph.size
232
- break
233
- end
234
- end
235
- live_objects.clear # to avoid making it a central node in future calls
236
- return graph
237
- end
238
-
239
- def collapse(*klasses)
240
- vertices = graph.vertices.dup
241
- vertices.each do |v|
242
- case v.obj
243
- when *klasses
244
- next if v.root?(graph) || v.leaf?(graph)
245
-
246
- v.each_parent_vertex(graph) do |parent|
247
- all_parent_info = parent[v, graph]
248
- v.each_child_vertex(graph) do |child|
249
- all_child_info = v[child, graph]
250
- all_parent_info.each do |parent_info|
251
- all_child_info.each do |child_info|
252
- add_reference(parent, child, parent_info + "." + child_info)
253
- end
254
- end
255
- end
256
- end
257
- graph.remove(v)
258
- end
259
- end
260
- end
261
-
262
- def live_chain_for(obj)
263
- result = []
264
-
265
- # Find one Roby task and look at the chain
266
- ref = references[obj.object_id]
267
- stack = [[ref.obj]]
268
- graph.reverse.each_dfs(ref, BGL::Graph::TREE) do |source, target, info, kind|
269
- source = source.obj
270
- target = target.obj
271
- if stack.last.first.object_id != source.object_id && stack.any? { |obj, _| obj.object_id == source.object_id }
272
- result << stack.dup if stack.size != 1
273
- while stack.last.first.object_id != source.object_id
274
- stack.pop
275
- end
276
- end
277
- stack.push [target, info]
278
- end
279
- if stack.size != 1
280
- result << stack
281
- end
282
- result
283
- end
284
-
285
-
286
- def display_live_chains(chains)
287
- chains.each do |stack|
288
- puts stack.map { |obj, link| "#{link} #{obj}" }.join("\n >")
289
- end
290
- end
291
-
292
- def to_dot
293
- roots = graph.vertices.find_all do |v|
294
- v.root?(graph)
295
- end.to_value_set
296
-
297
- io = StringIO.new("")
298
-
299
- colors = Hash[
300
- :green => 'green',
301
- :magenta => 'magenta',
302
- :black => 'black'
303
- ]
304
- obj_label_format = "obj%i [label=\"%s\",color=%s];"
305
- obj_label_format_elements = []
306
- edge_label_format_0 = "obj%i -> obj%i [label=\""
307
- edge_label_format_1 = "\"];"
308
- edge_label_format_elements = []
309
-
310
- all_seen = ValueSet.new
311
- seen = ValueSet.new
312
- io.puts "digraph {"
313
- roots.each do |obj_ref|
314
- graph.each_dfs(obj_ref, BGL::Graph::ALL) do |from_ref, to_ref, all_info, kind|
315
- info = []
316
- for str in all_info
317
- info << str
318
- end
319
-
320
- if all_seen.include?(from_ref)
321
- graph.prune
322
- else
323
- from_id = from_ref.obj.object_id
324
- to_id = to_ref.obj.object_id
325
-
326
- edge_label_format_elements.clear
327
- edge_label_format_elements << from_id << to_id
328
- str = edge_label_format_0 % edge_label_format_elements
329
- first = true
330
- for edge_info in all_info
331
- if !first
332
- str << ","
333
- end
334
- str << edge_info
335
- first = false
336
- end
337
- str << edge_label_format_1
338
-
339
- io.puts str
340
- end
341
- seen << from_ref << to_ref
342
- end
343
-
344
- for obj_ref in seen
345
- if !all_seen.include?(obj_ref)
346
- obj = obj_ref.obj
347
- obj_id = obj_ref.obj.object_id
348
- str =
349
- if obj.respond_to?(:each)
350
- "#{obj.class}: #{obj.object_id}"
351
- else
352
- obj.to_s
353
- end
354
-
355
- str = str.encode('UTF-8', :invalid => :replace, :undef => :replace, :replace => "")
356
- str = str.gsub(/[^\w\.:<>]/, "")
357
-
358
- color =
359
- if obj.kind_of?(BGL::Graph)
360
- :magenta
361
- elsif obj.kind_of?(Hash) || obj.kind_of?(Array) || obj.kind_of?(ValueSet)
362
- :green
363
- else
364
- :black
365
- end
366
-
367
- obj_label_format_elements = [obj_id, str.gsub(/[\\"\n]/, " "), colors[color]]
368
- str = obj_label_format % obj_label_format_elements
369
- io.puts(str)
370
- end
371
- end
372
- all_seen.merge(seen)
373
- seen.clear
374
- end
375
- roots.clear
376
- all_seen.clear
377
- seen.clear
378
- io.puts "}"
379
- io.string
380
- end
381
- end
382
- end
383
- end
384
-
@@ -1,9 +0,0 @@
1
- prefix=a_prefix
2
-
3
- Name: test_pkgconfig
4
- Description:
5
- Version: 4.2
6
-
7
- Cflags: -I${prefix}/include -O3
8
- Libs: -ltest -lother -L${prefix}/lib
9
-
@@ -1,10 +0,0 @@
1
- prefix=a_prefix
2
-
3
- Name: test_pkgconfig
4
- Description:
5
- Version: 4.2
6
-
7
- Cflags:
8
- Libs:
9
-
10
-
data/test/test_array.rb DELETED
@@ -1,15 +0,0 @@
1
- require './test/test_config'
2
- require 'utilrb/array'
3
-
4
- class TC_Array < Test::Unit::TestCase
5
- def test_to_s
6
- assert_equal("[1, 2]", [1, 2].to_s)
7
- end
8
- def test_to_s_recursive
9
- obj = [1, 2]
10
- obj << obj
11
- assert_equal("[1, 2, ...]", obj.to_s)
12
- end
13
-
14
- end
15
-
data/test/test_config.rb DELETED
@@ -1,4 +0,0 @@
1
- require 'test/unit'
2
- $LOAD_PATH.unshift File.expand_path('../lib', File.dirname(__FILE__))
3
- BASE_TEST_DIR=File.expand_path(File.dirname(__FILE__)) unless defined? BASE_TEST_DIR
4
-
data/test/test_dir.rb DELETED
@@ -1,22 +0,0 @@
1
- require './test/test_config'
2
-
3
- require 'utilrb/dir'
4
- require 'enumerator'
5
-
6
- class TC_Dir < Test::Unit::TestCase
7
- def test_empty
8
- this_dir = File.dirname(__FILE__)
9
- assert(!Dir.new(this_dir).empty?)
10
-
11
- begin
12
- Dir.mkdir(test_dir_path = File.join(this_dir, 'test_empty') )
13
- rescue Errno::EEXIST
14
- end
15
-
16
- test_dir = Dir.new(test_dir_path)
17
- assert(test_dir.empty?)
18
- ensure
19
- Dir.delete(test_dir_path) if test_dir_path
20
- end
21
- end
22
-
@@ -1,119 +0,0 @@
1
- require './test/test_config'
2
-
3
- require 'utilrb/enumerable'
4
- require 'utilrb/value_set'
5
-
6
- class TC_Enumerable < Test::Unit::TestCase
7
-
8
- def test_enum_uniq
9
- # Test the enum_uniq enumerator
10
- assert_equal([:a, :b, :c], [:a, :b, :a, :c].enum_uniq { |k| k }.to_a)
11
- assert_equal([:a, :b, :c], [:a, :b, :a, :c].enum_uniq.to_a)
12
- enum = [:a, :b, :a, :c].enum_uniq
13
- assert_equal(enum, enum.each)
14
-
15
- a, b, c, d = [1, 2], [1, 3], [2, 3], [3, 4]
16
-
17
- test = [a, b, c, d]
18
- assert_equal([a, c, d], test.enum_uniq { |x, y| x }.to_a)
19
- assert_equal([a, b, d], test.enum_uniq { |x, y| y }.to_a)
20
-
21
- klass = Class.new do
22
- def initialize(base); @base = base end
23
- def each(&iterator); @base.each { |x, y| yield [x, y] } end
24
- include Enumerable
25
- end
26
- test = klass.new(test)
27
- assert_equal([a, c, d], test.enum_uniq { |x, y| x }.to_a)
28
- assert_equal([a, b, d], test.enum_uniq { |x, y| y }.to_a)
29
-
30
- klass = Struct.new :x, :y
31
- test = test.map { |x, y| klass.new(x, y) }
32
- a, b, c, d = *test
33
- assert_equal([a, c, d], [a, b, c, d].enum_uniq { |v| v.x }.to_a)
34
- assert_equal([a, b, d], [a, b, c, d].enum_uniq { |v| v.y }.to_a)
35
- end
36
-
37
- def test_each_uniq
38
- assert_equal([:a, :b, :c], [:a, :b, :a, :c].enum_for(:each_uniq).to_a)
39
- end
40
-
41
- def test_enum_sequence
42
- c1 = [:a, :b, :c]
43
- c2 = [:d, :e, :f]
44
- assert_equal([:a, :b, :c, :d, :e, :f], (c1.to_enum + c2.to_enum).to_a)
45
- assert_equal([:a, :b, :c, :d, :e, :f], [c1, c2].inject(null_enum) { |a, b| a + b }.to_a)
46
- assert_equal([:a, :b, :c, :d, :e, :f], [c1, c2].inject(SequenceEnumerator.new) { |a, b| a << b }.to_a)
47
- end
48
-
49
- def test_random_element
50
- # Test on arrays
51
- set = (1..100).to_a
52
- 100.times { set.delete(set.random_element) }
53
- assert(set.empty?)
54
- assert_equal(nil, [].random_element)
55
-
56
- # Test on non-empty collection which defines #size
57
- set = Hash[*(1..100).map { |i| [i.to_s, i] }.flatten]
58
- 100.times { set.delete(set.random_element.first) }
59
- assert(set.empty?)
60
- assert_equal(nil, {}.random_element)
61
- end
62
-
63
- Utilrb.require_ext('test_value_set') do
64
- def test_value_set
65
- a = [1, 3, 3, 4, 6, 8].to_value_set
66
- b = [1, 2, 4, 3, 11, 11].to_value_set
67
- assert_equal(5, a.size)
68
- assert_equal([1, 3, 4, 6, 8], a.to_a)
69
- assert(a.include?(1))
70
- assert(a.include_all?([4, 1, 8].to_value_set))
71
- assert(!a.include_all?(b))
72
-
73
- assert(a.intersects?(b))
74
- assert(b.intersects?(a))
75
- assert(!a.intersects?([2, 9, 12].to_value_set))
76
-
77
- assert(a.object_id == a.to_value_set.object_id)
78
-
79
- assert_equal([1, 2, 3, 4, 6, 8, 11], (a.union(b)).to_a)
80
- assert_equal([1, 3, 4], (a.intersection(b)).to_a)
81
- assert_equal([6, 8], (a.difference(b)).to_a)
82
- assert(! (a == :bla)) # check #== behaves correctly with a non-enumerable
83
-
84
- a.delete(1)
85
- assert(! a.include?(1))
86
- a.merge(b);
87
- assert_equal([1, 2, 3, 4, 6, 8, 11].to_value_set, a)
88
-
89
- assert([].to_value_set.empty?)
90
-
91
- assert([1, 2, 4, 3].to_value_set.clear.empty?)
92
-
93
- assert_equal([1,3,5].to_value_set, [1, 2, 3, 4, 5, 6].to_value_set.delete_if { |v| v % 2 == 0 })
94
- end
95
-
96
- def test_value_set_hash
97
- a = [(obj = Object.new), 3, 4, [(obj2 = Object.new), Hash.new]].to_value_set
98
- b = [obj, 3, 4, [obj2, Hash.new]].to_value_set
99
- assert_equal a.hash, b.hash
100
- end
101
-
102
- def test_value_set_to_s
103
- obj = ValueSet.new
104
- obj << 1
105
- obj << 2
106
- assert(obj.to_s =~ /\{(.*)\}/)
107
- values = $1.split(", ")
108
- assert_equal(["1", "2"].to_set, values.to_set)
109
-
110
- obj << obj
111
- assert(obj.to_s =~ /^(.+)\{(.*)\}>$/)
112
-
113
- base_s = $1
114
- values = $2.split(", ")
115
- assert_equal(["1", "2", "#{base_s}...>"].to_set, values.to_set)
116
- end
117
- end
118
- end
119
-