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,341 +0,0 @@
1
- require 'utilrb/object/attribute'
2
- require 'utilrb/object/singleton_class'
3
- require 'utilrb/enumerable/uniq'
4
- require 'utilrb/module/include'
5
-
6
- module Utilrb
7
- module Models
8
- # Helper method for inherited_enumerable
9
- #
10
- # It is called in the context of the singleton class of the module/class on
11
- # which inherited_enumerable is called
12
- def define_inherited_enumerable(name, attribute_name = name, options = Hash.new, &init) # :nodoc:
13
- # Set up the attribute accessor
14
- attribute(attribute_name, &init)
15
- class_eval { private "#{attribute_name}=" }
16
-
17
- promote = method_defined?("promote_#{name}")
18
- options[:enum_with] ||= :each
19
-
20
- class_eval <<-EOF, __FILE__, __LINE__+1
21
- def all_#{name}; each_#{name}.to_a end
22
- def self_#{name}; @#{attribute_name} end
23
- EOF
24
-
25
- if options[:map]
26
- class_eval <<-EOF, __FILE__, __LINE__+1
27
- def find_#{name}(key)
28
- raise ArgumentError, "nil cannot be used as a key in find_#{name}" if !key
29
- each_#{name}(key, true) do |value|
30
- return value
31
- end
32
- nil
33
- end
34
- def has_#{name}?(key)
35
- ancestors = self.ancestors
36
- if ancestors.first != self
37
- ancestors.unshift self
38
- end
39
- for klass in ancestors
40
- if klass.instance_variable_defined?(:@#{attribute_name})
41
- return true if klass.#{attribute_name}.has_key?(key)
42
- end
43
- end
44
- false
45
- end
46
- EOF
47
- end
48
-
49
- class_eval <<-EOF, __FILE__, __LINE__+1
50
- def clear_#{attribute_name}
51
- #{attribute_name}.clear
52
- for klass in ancestors
53
- if klass.instance_variable_defined?(:@#{attribute_name})
54
- klass.#{attribute_name}.clear
55
- end
56
- end
57
- end
58
- EOF
59
-
60
- if !promote
61
- if options[:map]
62
- define_inherited_enumerable_map_without_promotion(name, attribute_name, options)
63
- else
64
- define_inherited_enumerable_nomap_without_promotion(name, attribute_name, options)
65
- end
66
- else
67
- if options[:map]
68
- define_inherited_enumerable_map_with_promotion(name, attribute_name, options)
69
- else
70
- define_inherited_enumerable_nomap_with_promotion(name, attribute_name, options)
71
- end
72
- end
73
- end
74
-
75
- def define_inherited_enumerable_map_without_promotion(name, attribute_name, options)
76
- class_eval <<-EOF, __FILE__, __LINE__+1
77
- def each_#{name}(key = nil, uniq = true)
78
- if !block_given?
79
- return enum_for(:each_#{name}, key, uniq)
80
- end
81
-
82
- ancestors = self.ancestors
83
- if ancestors.first != self
84
- ancestors.unshift self
85
- end
86
- if key
87
- for klass in ancestors
88
- if klass.instance_variable_defined?(:@#{attribute_name})
89
- if klass.#{attribute_name}.has_key?(key)
90
- yield(klass.#{attribute_name}[key])
91
- return self if uniq
92
- end
93
- end
94
- end
95
- elsif !uniq
96
- for klass in ancestors
97
- if klass.instance_variable_defined?(:@#{attribute_name})
98
- klass.#{attribute_name}.#{options[:enum_with]} do |el|
99
- yield(el)
100
- end
101
- end
102
- end
103
- else
104
- seen = Set.new
105
- for klass in ancestors
106
- if klass.instance_variable_defined?(:@#{attribute_name})
107
- klass.#{attribute_name}.#{options[:enum_with]} do |el|
108
- unless seen.include?(el.first)
109
- seen << el.first
110
- yield(el)
111
- end
112
- end
113
- end
114
- end
115
-
116
- end
117
- self
118
- end
119
- EOF
120
- end
121
-
122
- def define_inherited_enumerable_nomap_without_promotion(name, attribute_name, options)
123
- class_eval <<-EOF, __FILE__, __LINE__+1
124
- def each_#{name}
125
- if !block_given?
126
- return enum_for(:each_#{name})
127
- end
128
-
129
- ancestors = self.ancestors
130
- if ancestors.first != self
131
- ancestors.unshift self
132
- end
133
- for klass in ancestors
134
- if klass.instance_variable_defined?(:@#{attribute_name})
135
- klass.#{attribute_name}.#{options[:enum_with]} { |el| yield(el) }
136
- end
137
- end
138
- self
139
- end
140
- EOF
141
- end
142
-
143
- def define_inherited_enumerable_map_with_promotion(name, attribute_name, options)
144
- class_eval <<-EOF, __FILE__, __LINE__+1
145
- def each_#{name}(key = nil, uniq = true)
146
- if !block_given?
147
- return enum_for(:each_#{name}, key, uniq)
148
- end
149
-
150
- ancestors = self.ancestors
151
- if ancestors.first != self
152
- ancestors.unshift self
153
- end
154
- if key
155
- promotions = []
156
- for klass in ancestors
157
- if klass.instance_variable_defined?(:@#{attribute_name})
158
- if klass.#{attribute_name}.has_key?(key)
159
- value = klass.#{attribute_name}[key]
160
- for p in promotions
161
- value = p.promote_#{name}(key, value)
162
- end
163
- yield(value)
164
- return self if uniq
165
- end
166
- end
167
- promotions.unshift(klass) if klass.respond_to?("promote_#{name}")
168
- end
169
- elsif !uniq
170
- promotions = []
171
- for klass in ancestors
172
- if klass.instance_variable_defined?(:@#{attribute_name})
173
- klass.#{attribute_name}.#{options[:enum_with]} do |key, value|
174
- for p in promotions
175
- value = p.promote_#{name}(key, value)
176
- end
177
- yield(key, value)
178
- end
179
- end
180
- promotions.unshift(klass) if klass.respond_to?("promote_#{name}")
181
- end
182
- else
183
- seen = Set.new
184
- promotions = []
185
- for klass in ancestors
186
- if klass.instance_variable_defined?(:@#{attribute_name})
187
- klass.#{attribute_name}.#{options[:enum_with]} do |key, value|
188
- unless seen.include?(key)
189
- for p in promotions
190
- value = p.promote_#{name}(key, value)
191
- end
192
- seen << key
193
- yield(key, value)
194
- end
195
- end
196
- end
197
- promotions.unshift(klass) if klass.respond_to?("promote_#{name}")
198
- end
199
- end
200
- self
201
- end
202
- EOF
203
- end
204
-
205
- def define_inherited_enumerable_nomap_with_promotion(name, attribute_name, options)
206
- class_eval <<-EOF, __FILE__, __LINE__+1
207
- def each_#{name}
208
- if !block_given?
209
- return enum_for(:each_#{name})
210
- end
211
-
212
- ancestors = self.ancestors
213
- if ancestors.first != self
214
- ancestors.unshift self
215
- end
216
- promotions = []
217
- for klass in ancestors
218
- if klass.instance_variable_defined?(:@#{attribute_name})
219
- klass.#{attribute_name}.#{options[:enum_with]} do |value|
220
- for p in promotions
221
- value = p.promote_#{name}(value)
222
- end
223
- yield(value)
224
- end
225
- end
226
- promotions.unshift(klass) if klass.respond_to?("promote_#{name}")
227
- end
228
- self
229
- end
230
- EOF
231
- end
232
-
233
- # Defines an attribute as being enumerable in the class instance and in the
234
- # whole class inheritance hierarchy. More specifically, it defines a
235
- # <tt>each_#{name}(&iterator)</tt> instance method and a <tt>each_#{name}(&iterator)</tt>
236
- # class method which iterates (in order) on
237
- # - the instance #{name} attribute
238
- # - the singleton class #{name} attribute
239
- # - the class #{name} attribute
240
- # - the superclass #{name} attribute
241
- # - the superclass' superclass #{name} attribute
242
- # ...
243
- #
244
- # This method can be used on modules, in which case the module is used as if
245
- # it was part of the inheritance hierarchy.
246
- #
247
- # The +name+ option defines the enumeration method name (+value+ will
248
- # define a +each_value+ method). +attribute_name+ defines the attribute
249
- # name. +init+ is a block called to initialize the attribute.
250
- # Valid options in +options+ are:
251
- # map::
252
- # If true, the attribute should respond to +[]+. In that case, the
253
- # enumeration method is each_value(key = nil, uniq = false) If +key+ is
254
- # given, we iterate on the values given by <tt>attribute[key]</tt>. If
255
- # +uniq+ is true, the enumeration will yield at most one value for each
256
- # +key+ found (so, if both +key+ and +uniq+ are given, the enumeration
257
- # yields at most one value). See the examples below
258
- # enum_with:: the enumeration method of the enumerable, if it is not +each+
259
- #
260
- # === Example
261
- # Let's define some classes and look at the ancestor chain
262
- #
263
- # class A; end
264
- # module M; end
265
- # class B < A; include M end
266
- # A.ancestors # => [A, Object, Kernel]
267
- # B.ancestors # => [B, M, A, Object, Kernel]
268
- #
269
- # ==== Attributes for which 'map' is not set
270
- #
271
- # class A
272
- # inherited_enumerable("value", "values") do
273
- # Array.new
274
- # end
275
- # end
276
- # module M
277
- # inherited_enumerable("mod") do
278
- # Array.new
279
- # end
280
- # end
281
- #
282
- # A.values << 1 # => [1]
283
- # B.values << 2 # => [2]
284
- # M.mod << 1 # => [1]
285
- # b = B.new
286
- # class << b
287
- # self.values << 3 # => [3]
288
- # self.mod << 4 # => [4]
289
- # end
290
- # M.mod << 2 # => [1, 2]
291
- #
292
- # A.enum_for(:each_value).to_a # => [1]
293
- # B.enum_for(:each_value).to_a # => [2, 1]
294
- # b.singleton_class.enum_for(:each_value).to_a # => [3, 2, 1]
295
- # b.singleton_class.enum_for(:each_mod).to_a # => [4, 1, 2]
296
- #
297
- # ==== Attributes for which 'map' is set
298
- #
299
- # class A
300
- # inherited_enumerable("mapped", "map", :map => true) do
301
- # Hash.new { |h, k| h[k] = Array.new }
302
- # end
303
- # end
304
- #
305
- # A.map['name'] = 'A' # => "A"
306
- # A.map['universe'] = 42
307
- # B.map['name'] = 'B' # => "B"
308
- # B.map['half_of_it'] = 21
309
- #
310
- # Let's see what happens if we don't specify the key option.
311
- # A.enum_for(:each_mapped).to_a # => [["name", "A"], ["universe", 42]]
312
- # If the +uniq+ option is set (the default), we see only B's value for 'name'
313
- # B.enum_for(:each_mapped).to_a # => [["half_of_it", 21], ["name", "B"], ["universe", 42]]
314
- # If the +uniq+ option is not set, we see both values for 'name'. Note that
315
- # since 'map' is a Hash, the order of keys in one class is not guaranteed.
316
- # Nonetheless, we have the guarantee that values from B appear before
317
- # those from A
318
- # B.enum_for(:each_mapped, nil, false).to_a # => [["half_of_it", 21], ["name", "B"], ["name", "A"], ["universe", 42]]
319
- #
320
- #
321
- # Now, let's see how 'key' behaves
322
- # A.enum_for(:each_mapped, 'name').to_a # => ["A"]
323
- # B.enum_for(:each_mapped, 'name').to_a # => ["B"]
324
- # B.enum_for(:each_mapped, 'name', false).to_a # => ["B", "A"]
325
- #
326
- def inherited_enumerable(name, attribute_name = name, options = Hash.new, &init)
327
- singleton_class.class_eval { define_inherited_enumerable(name, attribute_name, options, &init) }
328
-
329
- if is_a?(Module) && !is_a?(Class)
330
- unless const_defined_here?(:ClassExtension)
331
- const_set(:ClassExtension, Module.new)
332
- end
333
- class_extension = const_get(:ClassExtension)
334
- class_extension.class_eval do
335
- define_inherited_enumerable(name, attribute_name, options, &init)
336
- end
337
- end
338
- end
339
- end
340
- end
341
-
@@ -1,115 +0,0 @@
1
- require 'facets/kernel/call_stack'
2
- require 'utilrb/object/attribute'
3
- require 'utilrb/module/attr_predicate'
4
- module Utilrb
5
- module Models
6
-
7
- # Handling of registration of model hierarchies
8
- #
9
- # It depends on the mixed-in object to provide a #supermodel method that
10
- # returns the model that is parent of +self+
11
- module Registration
12
- # The place where this model got defined in the source code
13
- # The tuple is (file,lineno,method), and can be obtained with
14
- # facet's #call_stack
15
- # @return [Array<(String,Integer,Symbol)>]
16
- attr_accessor :definition_location
17
-
18
- # Tells {#clear_submodels} whether this model should be removed from
19
- # the model set or not. The default is false (it should be removed)
20
- #
21
- # @return [Boolean]
22
- attr_predicate :permanent_model?, true
23
-
24
- # [ValueSet] the set of models that are children of this one
25
- attribute(:submodels) { ValueSet.new }
26
-
27
- # Returns the model that is parent of this one
28
- #
29
- # The default implementation returns superclass if it is extended by
30
- # this Registration module, and nil otherwise
31
- def supermodel
32
- if superclass.respond_to?(:register_submodel)
33
- superclass
34
- end
35
- end
36
-
37
- # Call to register a model that is a submodel of +self+
38
- def register_submodel(klass)
39
- if !klass.definition_location
40
- klass.definition_location = call_stack
41
- end
42
-
43
- if klass.name && !klass.permanent_model?
44
- begin
45
- if constant("::#{klass.name}") == klass
46
- klass.permanent_model = true
47
- end
48
- rescue NameError
49
- end
50
- end
51
-
52
- submodels << klass
53
- if m = supermodel
54
- m.register_submodel(klass)
55
- end
56
- end
57
-
58
- # Enumerates all models that are submodels of this class
59
- def each_submodel
60
- return enum_for(:each_submodel) if !block_given?
61
- submodels.each do |obj|
62
- yield(obj)
63
- end
64
- end
65
-
66
- # Clears all registered submodels
67
- def clear_submodels
68
- children = self.submodels.find_all { |m| !m.permanent_model? }
69
- if !deregister_submodels(children)
70
- return
71
- end
72
-
73
- # This contains the permanent submodels
74
- #
75
- # We can call #clear_submodels while iterating here as it is a
76
- # constraint that all models in #submodels are permanent (and
77
- # will therefore not be removed)
78
- submodels.each { |m| m.clear_submodels }
79
- # And this the non-permanent ones
80
- children.each { |m| m.clear_submodels }
81
- true
82
- end
83
-
84
- # Deregisters a set of submodels on this model and all its
85
- # supermodels
86
- #
87
- # This is usually not called directly. Use #clear_submodels instead
88
- #
89
- # @param [ValueSet] set the set of submodels to remove
90
- def deregister_submodels(set)
91
- current_size = submodels.size
92
- submodels.difference!(set.to_value_set)
93
- if (submodels.size != current_size)
94
- if m = supermodel
95
- m.deregister_submodels(set)
96
- end
97
- true
98
- else false
99
- end
100
- end
101
-
102
- # Registers submodels when a subclass is created (when models are
103
- # represented as classes)
104
- def inherited(subclass)
105
- subclass.definition_location = call_stack
106
- super
107
- register_submodel(subclass)
108
- subclass.permanent_model = true
109
- end
110
- end
111
- end
112
- end
113
-
114
-
115
-
@@ -1,6 +0,0 @@
1
- require 'utilrb/models/inherited_enumerable'
2
-
3
- class Module
4
- include Utilrb::Models
5
- end
6
-
@@ -1,193 +0,0 @@
1
- require 'utilrb/gc/force'
2
- require 'utilrb/object/attribute'
3
- require 'utilrb/column_formatter'
4
-
5
- module ObjectStats
6
- # The count of objects currently allocated
7
- #
8
- # It allocates no objects, which means that if
9
- # a = ObjectStats.count
10
- # b = ObjectStats.count
11
- # then a == b
12
- def self.count
13
- count = 0
14
- ObjectSpace.each_object { |obj| count += 1 }
15
-
16
- count
17
- end
18
-
19
- # Returns a klass => count hash counting the currently allocated objects
20
- #
21
- # It allocates 1 Hash, which is included in the count
22
- def self.count_by_class(threshold = nil)
23
- by_class = Hash.new(0)
24
- ObjectSpace.each_object { |obj|
25
- by_class[obj.class] += 1
26
- by_class
27
- }
28
- if threshold
29
- by_class.delete_if { |kl, count| count < threshold }
30
- end
31
-
32
- by_class
33
- end
34
-
35
- LIVE_OBJECTS_KEY = :live_objects
36
-
37
- # Profiles how much objects has been allocated by the block. Returns a
38
- # klass => count hash like count_by_class
39
- #
40
- # If alive is true, then only live objects are returned.
41
- def self.profile(alive = false)
42
- if alive
43
- GC.force
44
- profile do
45
- yield
46
- GC.force
47
- end
48
- end
49
-
50
- already_disabled = GC.disable
51
- before = count_by_class
52
- if ObjectSpace.respond_to?(:live_objects)
53
- before_live_objects = ObjectSpace.live_objects
54
- end
55
- yield
56
- if ObjectSpace.respond_to?(:live_objects)
57
- after_live_objects = ObjectSpace.live_objects
58
- end
59
- after = count_by_class
60
- if after_live_objects
61
- before[LIVE_OBJECTS_KEY] = before_live_objects
62
- after[LIVE_OBJECTS_KEY] = after_live_objects - 1 # correction for yield
63
- end
64
- GC.enable unless already_disabled
65
-
66
- after[Hash] -= 1 # Correction for the call of count_by_class
67
- profile = before.
68
- merge(after) { |klass, old, new| new - old }.
69
- delete_if { |klass, count| count == 0 }
70
- end
71
- end
72
-
73
- # BenchmarkAllocation is a Benchmark-like interface to benchmark object allocation.
74
- #
75
- # == Formatting
76
- # BenchmarkAllocation formats its output in two ways (see examples below)
77
- # * first, each part of a class path is displayed in its own line, to reduce
78
- # the output width
79
- # * then, output is formatted so that it does not exceed
80
- # BenchmarkAllocation::SCREEN_WIDTH width
81
- #
82
- #
83
- # == Examples
84
- #
85
- # For instance,
86
- #
87
- # require 'utilrb/objectstats'
88
- #
89
- # module Namespace
90
- # class MyClass
91
- # end
92
- # end
93
- #
94
- # BenchmarkAllocation.bm do |x|
95
- # x.report("array") { Array.new }
96
- # x.report("hash") { Hash.new }
97
- # x.report("myclass") { MyClass.new }
98
- # end
99
- #
100
- # will produce the output
101
- #
102
- # Array Hash Namespace::
103
- # MyClass
104
- # array 1 - -
105
- # hash - 1 -
106
- # myclass - - 1
107
- #
108
- # Like Benchmark, a rehearsal benchmark method, BenchmarkAllocation.bmbm
109
- # is provided:
110
- #
111
- # require 'utilrb/objectstats'
112
- # require 'delegate'
113
- #
114
- # module Namespace
115
- # class MyClass
116
- # end
117
- # end
118
- #
119
- # delegate_klass = nil
120
- # BenchmarkAllocation.bmbm do |x|
121
- # x.report("array") { Array.new }
122
- # x.report("hash") { Hash.new }
123
- # x.report("myclass") { Namespace::MyClass.new }
124
- # x.report("delegate") do
125
- # delegate_klass ||= Class.new(DelegateClass(Namespace::MyClass)) do
126
- # def self.name; "Delegate(MyClass)" end
127
- # end
128
- # delegate_klass.new(Namespace::MyClass.new)
129
- # end
130
- # end
131
- #
132
- # produces
133
- #
134
- # Rehearsal --------------------------------------------------------------------------------
135
- #
136
- # Array Class Delegate(MyClass) Hash Namespace:: String
137
- # MyClass
138
- # array 1 - - - - -
139
- # hash - - - 1 - -
140
- # myclass - - - - 1 -
141
- # delegate 5 2 1 2 1 247
142
- # ------------------------------------------------------------------------------------------
143
- #
144
- # Array Delegate(MyClass) Hash Namespace::
145
- # MyClass
146
- # array 1 - - -
147
- # hash - - 1 -
148
- # myclass - - - 1
149
- # delegate - 1 - 1
150
- #
151
- class BenchmarkAllocation
152
- SCREEN_WIDTH = 90
153
- MARGIN = 2
154
-
155
- def self.bm(label_width = nil)
156
- yield(gather = new)
157
- gather.format
158
- end
159
- def self.bmbm(label_width = nil)
160
- yield(gather = new)
161
-
162
- title = "Rehearsal"
163
- puts title + " " + "-" * (SCREEN_WIDTH - title.length - 1)
164
- gather.format
165
- puts "-" * SCREEN_WIDTH
166
-
167
- yield(gather = new)
168
- gather.format
169
- end
170
-
171
- def format(screen_width = SCREEN_WIDTH, margin = MARGIN)
172
- data = profiles.map do |label, line_data|
173
- line_data['label'] = label
174
- line_data
175
- end
176
- ColumnFormatter.from_hashes(data, screen_width)
177
- end
178
-
179
- attribute(:profiles) { Array.new }
180
- def report(label)
181
- result = ObjectStats.profile do
182
- yield
183
- end
184
- result.inject({}) do |result, (klass, count)|
185
- klass = klass.to_s
186
- klass = "unknown" if !klass || klass.empty?
187
- result[klass] = count
188
- result
189
- end
190
- profiles << [label, result]
191
- end
192
- end
193
-