utilrb 1.0 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: