utilrb 2.0.2.b2 → 2.1.0.rc1

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 (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
-