utilrb 1.0 → 1.1

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.
@@ -1,5 +1,6 @@
1
1
  require 'utilrb/gc/force'
2
2
  require 'utilrb/object/attribute'
3
+ require 'utilrb/column_formatter'
3
4
 
4
5
  module ObjectStats
5
6
  # The count of objects currently allocated
@@ -24,9 +25,12 @@ module ObjectStats
24
25
  by_class[obj.class] += 1
25
26
  by_class
26
27
  }
28
+
27
29
  by_class
28
30
  end
29
31
 
32
+ LIVE_OBJECTS_KEY = :live_objects
33
+
30
34
  # Profiles how much objects has been allocated by the block. Returns a
31
35
  # klass => count hash like count_by_class
32
36
  #
@@ -42,8 +46,18 @@ module ObjectStats
42
46
 
43
47
  already_disabled = GC.disable
44
48
  before = count_by_class
49
+ if ObjectSpace.respond_to?(:live_objects)
50
+ before_live_objects = ObjectSpace.live_objects
51
+ end
45
52
  yield
53
+ if ObjectSpace.respond_to?(:live_objects)
54
+ after_live_objects = ObjectSpace.live_objects
55
+ end
46
56
  after = count_by_class
57
+ if after_live_objects
58
+ before[LIVE_OBJECTS_KEY] = before_live_objects
59
+ after[LIVE_OBJECTS_KEY] = after_live_objects - 1 # correction for yield
60
+ end
47
61
  GC.enable unless already_disabled
48
62
 
49
63
  after[Hash] -= 1 # Correction for the call of count_by_class
@@ -132,8 +146,8 @@ end
132
146
  # delegate - 1 - 1
133
147
  #
134
148
  class BenchmarkAllocation
135
- MARGIN = 2
136
149
  SCREEN_WIDTH = 90
150
+ MARGIN = 2
137
151
 
138
152
  def self.bm(label_width = nil)
139
153
  yield(gather = new)
@@ -152,58 +166,11 @@ class BenchmarkAllocation
152
166
  end
153
167
 
154
168
  def format(screen_width = SCREEN_WIDTH, margin = MARGIN)
155
- label_width ||= 0
156
- column_names = profiles.inject([]) do |column_names, (label, profile)|
157
- label_width = label_width < label.length ? label.length : label_width
158
- column_names |= profile.keys
159
- end.sort
160
-
161
- # split at the :: to separate modules and klasses (reduce header sizes)
162
- blocks = []
163
- header, columns, current_width = nil
164
- column_names.each_with_index do |name, col_index|
165
- splitted = name.gsub(/::/, "::\n").split("\n")
166
- width = splitted.map { |part| part.length }.max + MARGIN
167
-
168
- if !current_width || (current_width + label_width + width > screen_width)
169
- # start a new block
170
- blocks << [[], []]
171
- header, columns = blocks.last
172
- current_width = 0
173
- end
174
-
175
- splitted.each_with_index do |part, line_index|
176
- if !header[line_index]
177
- header[line_index] = columns.map { |_, w| " " * w }
178
- end
179
- header[line_index] << "% #{width}s" % [part]
180
- end
181
- # Pad the remaining lines
182
- header[splitted.size..-1].each_with_index do |line, index|
183
- line << " " * width
184
- end
185
-
186
- columns << [name, width]
187
- current_width += width
188
- end
189
-
190
- blocks.each do |header, columns|
191
- puts
192
- header.each { |line| puts " " * label_width + line.join("") }
193
-
194
- profiles.each do |label, profile|
195
- print "% #{label_width}s" % [label]
196
- columns.each do |name, width|
197
-
198
- if count = profile[name]
199
- print "% #{width}i" % [profile[name] || 0]
200
- else
201
- print " " * (width - 1) + "-"
202
- end
203
- end
204
- puts
205
- end
169
+ data = profiles.map do |label, line_data|
170
+ line_data['label'] = label
171
+ line_data
206
172
  end
173
+ ColumnFormatter.from_hashes(data, screen_width)
207
174
  end
208
175
 
209
176
  attribute(:profiles) { Array.new }
@@ -212,7 +179,7 @@ class BenchmarkAllocation
212
179
  yield
213
180
  end
214
181
  result.inject({}) do |result, (klass, count)|
215
- klass = klass.name
182
+ klass = klass.to_s
216
183
  klass = "unknown" if !klass || klass.empty?
217
184
  result[klass] = count
218
185
  result
@@ -1,7 +1,11 @@
1
+ require 'utilrb/enumerable/to_s_helper'
1
2
  require 'set'
2
3
  class Set
4
+ # Displays the set as {a, b, c, d}
3
5
  def to_s
4
- "{ #{map { |o| o.to_s }.join(", ")} }"
6
+ EnumerableToString.to_s_helper(self, '{', '}') do |obj|
7
+ obj.to_s
8
+ end
5
9
  end
6
10
  end
7
11
 
@@ -8,29 +8,32 @@ class Time
8
8
  # Creates a Time object from a h:m:s.ms representation. The following formats are allowed:
9
9
  # s, s.ms, m:s, m:s.ms, h:m:s, h:m:s.ms
10
10
  def self.from_hms(string)
11
- unless string =~ /(?:^|:)(\d+)(?:$|\.)/
11
+ unless string =~ /(?:^|:)0*(\d*)(?:$|\.)/
12
12
  raise ArgumentError, "#{string} found, expected [[h:]m:]s[.ms]"
13
13
  end
14
14
  hm, ms = $`, $'
15
15
 
16
- s = Integer($1)
17
- unless hm =~ /^(?:(\d*):)?(?:(\d*))?$/
16
+ s = if $1.empty? then 0
17
+ else Integer($1)
18
+ end
19
+
20
+ unless hm =~ /^(?:0*(\d*):)?(?:0*(\d*))?$/
18
21
  raise ArgumentError, "found #{hm}, expected nothing, m: or h:m:"
19
22
  end
20
- h, m = if $2.empty? then
21
- if $1 then [0, Integer($1)]
22
- else [0, 0]
23
- end
24
- else [Integer($1), Integer($2)]
23
+
24
+ h, m = if (!$1 || $1.empty?) && $2.empty? then [0, 0]
25
+ elsif (!$1 || $1.empty?) then [0, Integer($2)]
26
+ elsif $2.empty? then [0, Integer($1)]
27
+ else
28
+ [Integer($1), Integer($2)]
25
29
  end
26
30
 
27
- ms = if ms.empty? then 0
31
+ ms = if ms =~ /^0*$/ then 0
28
32
  else
29
- unless ms =~ /^\d*$/
33
+ unless ms =~ /^(0*)([1-9]+)0*$/
30
34
  raise ArgumentError, "found #{string}, expected a number"
31
35
  end
32
- ms += "0" * (3 - ms.size)
33
- Integer(ms)
36
+ Integer($2) * (10 ** (2 - $1.length))
34
37
  end
35
38
 
36
39
  Time.at(Float(h * 3600 + m * 60 + s) + ms * 1.0e-3)
@@ -1,4 +1,6 @@
1
1
  class UnboundMethod
2
+ # Calls this method on +obj+ with the +args+ and +block+ arguments. This
3
+ # allows to have an uniform way to call methods on objects
2
4
  def call(obj, *args, &block)
3
5
  bind(obj).call(*args, &block)
4
6
  end
@@ -1,4 +1,5 @@
1
1
  require 'utilrb/common'
2
+ require 'utilrb/enumerable/to_s_helper'
2
3
 
3
4
  Utilrb.require_faster("ValueSet") do
4
5
  class ValueSet
@@ -9,17 +10,11 @@ Utilrb.require_faster("ValueSet") do
9
10
  include Enumerable
10
11
 
11
12
  def to_s
12
- stack = (Thread.current[:__value_set_stack__] ||= ValueSet.new)
13
- if stack.include?(self)
14
- "..."
15
- else
16
- stack << self
17
-
18
- base = super[0..-2]
19
- "#{base} { #{to_a.map { |o| o.to_s }.join(", ")} }"
13
+ elements = EnumerableToString.to_s_helper(self, '{', '}') do |obj|
14
+ obj.to_s
20
15
  end
21
- ensure
22
- stack.delete(self)
16
+ base = super[0..-2]
17
+ "#{base} #{elements}>"
23
18
  end
24
19
  alias :inspect :to_s
25
20
 
data/test/test_array.rb CHANGED
@@ -5,5 +5,11 @@ class TC_Array < Test::Unit::TestCase
5
5
  def test_to_s
6
6
  assert_equal("[1, 2]", [1, 2].to_s)
7
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
+
8
14
  end
9
15
 
@@ -93,10 +93,20 @@ class TC_Enumerable < Test::Unit::TestCase
93
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
94
  end
95
95
 
96
- def test_value_set_recursive_to_s
97
- v = [1, 2].to_value_set
98
- v << v
99
- assert_nothing_raised { v.to_s }
96
+ def test_value_set_to_s
97
+ obj = ValueSet.new
98
+ obj << 1
99
+ obj << 2
100
+ assert(obj.to_s =~ /\{(.*)\}/)
101
+ values = $1.split(", ")
102
+ assert_equal(["1", "2"].to_set, values.to_set)
103
+
104
+ obj << obj
105
+ assert(obj.to_s =~ /^(.+)\{(.*)\}>$/)
106
+
107
+ base_s = $1
108
+ values = $2.split(", ")
109
+ assert_equal(["1", "2", "#{base_s}...>"].to_set, values.to_set)
100
110
  end
101
111
  end
102
112
  end
data/test/test_hash.rb CHANGED
@@ -16,7 +16,15 @@ class TC_Hash < Test::Unit::TestCase
16
16
  end
17
17
 
18
18
  def test_to_s
19
- assert_equal("{1 => 2, 2 => 3}", { 1 => 2, 2 => 3 }.to_s)
19
+ obj = { 1 => 2, 2 => 3 }
20
+ assert(obj.to_s =~ /^\{(.*)\}$/)
21
+ values = $1.split(", ")
22
+ assert_equal(["1 => 2", "2 => 3"].to_set, values.to_set)
23
+
24
+ obj[3] = obj
25
+ assert(obj.to_s =~ /^\{(.*)\}$/)
26
+ values = $1.split(", ")
27
+ assert_equal(["1 => 2", "2 => 3", "3 => ..."].to_set, values.to_set)
20
28
  end
21
29
  end
22
30
 
@@ -1,6 +1,7 @@
1
1
  require 'test_config'
2
2
 
3
3
  require 'utilrb/objectstats'
4
+ require 'utilrb/hash/to_s'
4
5
 
5
6
  class TC_ObjectStats < Test::Unit::TestCase
6
7
  def teardown
@@ -9,11 +10,17 @@ class TC_ObjectStats < Test::Unit::TestCase
9
10
 
10
11
  def allocate_dead_hash; Hash.new; nil end
11
12
 
13
+ def assert_profile(expected, value, string = nil)
14
+ value = value.dup
15
+ value.delete(ObjectStats::LIVE_OBJECTS_KEY)
16
+ assert_equal(expected, value, (string || "") + " #{value}")
17
+ end
18
+
12
19
  def test_object_stats
13
- assert( ObjectStats.profile { ObjectStats.count }.empty?, "Object allocation profile changed" )
14
- assert_equal({ Hash => 1 }, ObjectStats.profile { ObjectStats.count_by_class }, "Object allocation profile changed")
15
- assert_equal({ Array => 1 }, ObjectStats.profile { test = [] })
16
- assert_equal({ Array => 2, Hash => 1 }, ObjectStats.profile { a, b = [], {} })
20
+ assert_profile({}, ObjectStats.profile { ObjectStats.count }, "Object allocation profile changed")
21
+ assert_profile({ Hash => 1 }, ObjectStats.profile { ObjectStats.count_by_class }, "Object allocation profile changed")
22
+ assert_profile({ Array => 1 }, ObjectStats.profile { test = [] })
23
+ assert_profile({ Array => 2, Hash => 1 }, ObjectStats.profile { a, b = [], {} })
17
24
  end
18
25
  end
19
26
 
data/test/test_set.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'test_config'
2
+ require 'utilrb/set'
3
+
4
+ class TC_Set < Test::Unit::TestCase
5
+ def test_to_s
6
+ obj = Set.new
7
+ obj << 1
8
+ obj << 2
9
+ assert(obj.to_s =~ /^\{(.*)\}$/)
10
+ values = $1.split(", ")
11
+ assert_equal(["1", "2"].to_set, values.to_set)
12
+
13
+ obj << obj
14
+ assert(obj.to_s =~ /^\{(.*)\}$/)
15
+ values = $1.split(", ")
16
+ assert_equal(["1", "2", "..."].to_set, values.to_set)
17
+ end
18
+ end
19
+
data/test/test_time.rb CHANGED
@@ -23,9 +23,12 @@ class TC_Time < Test::Unit::TestCase
23
23
 
24
24
  assert_equal(Time.at(0), Time.from_hms("0"))
25
25
  assert_equal(Time.at(0), Time.from_hms("0."))
26
- assert_in_delta(0, Time.at(1.2) - Time.from_hms("1.2"), 0.001)
26
+ assert_in_delta(0, Time.at(1.2) - Time.from_hms("1.2"), 0.001, Time.from_hms("1.2").to_hms)
27
27
  assert_in_delta(0, Time.at(121.3) - Time.from_hms("2:1.3"), 0.001)
28
28
  assert_in_delta(0, Time.at(3723.4) - Time.from_hms("1:2:3.4"), 0.001)
29
+ assert_in_delta(0, Time.at(1.02) - Time.from_hms("1.02"), 0.001)
30
+ assert_in_delta(0, Time.at(121.03) - Time.from_hms("2:1.03"), 0.001)
31
+ assert_in_delta(0, Time.at(3723.04) - Time.from_hms("1:2:3.04"), 0.001)
29
32
  end
30
33
  end
31
34
 
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.2
2
+ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: utilrb
5
5
  version: !ruby/object:Gem::Version
6
- version: "1.0"
7
- date: 2007-03-31 00:00:00 +02:00
6
+ version: "1.1"
7
+ date: 2007-06-19 00:00:00 +02:00
8
8
  summary: Yet another Ruby toolkit
9
9
  require_paths:
10
10
  - lib
@@ -45,11 +45,13 @@ files:
45
45
  - lib/utilrb.rb
46
46
  - lib/utilrb/array.rb
47
47
  - lib/utilrb/array/to_s.rb
48
+ - lib/utilrb/column_formatter.rb
48
49
  - lib/utilrb/common.rb
49
50
  - lib/utilrb/enumerable.rb
50
51
  - lib/utilrb/enumerable/null.rb
51
52
  - lib/utilrb/enumerable/random_element.rb
52
53
  - lib/utilrb/enumerable/sequence.rb
54
+ - lib/utilrb/enumerable/to_s_helper.rb
53
55
  - lib/utilrb/enumerable/uniq.rb
54
56
  - lib/utilrb/exception.rb
55
57
  - lib/utilrb/exception/full_message.rb
@@ -72,6 +74,7 @@ files:
72
74
  - lib/utilrb/module/ancestor_p.rb
73
75
  - lib/utilrb/module/attr_enumerable.rb
74
76
  - lib/utilrb/module/attr_predicate.rb
77
+ - lib/utilrb/module/cached_enum.rb
75
78
  - lib/utilrb/module/define_method.rb
76
79
  - lib/utilrb/module/include.rb
77
80
  - lib/utilrb/module/inherited_enumerable.rb
@@ -102,11 +105,13 @@ files:
102
105
  - test/test_objectstats.rb
103
106
  - test/test_pkgconfig.rb
104
107
  - test/test_proc.rb
108
+ - test/test_set.rb
105
109
  - test/test_time.rb
106
110
  - test/test_unbound_method.rb
107
111
  test_files:
108
112
  - test/test_proc.rb
109
113
  - test/test_exception.rb
114
+ - test/test_set.rb
110
115
  - test/test_time.rb
111
116
  - test/test_misc.rb
112
117
  - test/test_module.rb
@@ -120,10 +125,14 @@ test_files:
120
125
  - test/test_hash.rb
121
126
  - test/test_objectstats.rb
122
127
  - test/test_pkgconfig.rb
123
- rdoc_options: []
124
-
125
- extra_rdoc_files: []
126
-
128
+ rdoc_options:
129
+ - --main
130
+ - README.txt
131
+ extra_rdoc_files:
132
+ - Changes.txt
133
+ - License.txt
134
+ - Manifest.txt
135
+ - README.txt
127
136
  executables: []
128
137
 
129
138
  extensions: []
@@ -147,5 +156,5 @@ dependencies:
147
156
  requirements:
148
157
  - - ">="
149
158
  - !ruby/object:Gem::Version
150
- version: 1.2.0
159
+ version: 1.2.1
151
160
  version: