tryouts 0.8.8 → 2.0.0
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.
- data/.gitignore +1 -0
- data/LICENSE.txt +1 -1
- data/README.rdoc +64 -228
- data/Rakefile +42 -65
- data/VERSION.yml +5 -0
- data/bin/try +26 -0
- data/lib/sysinfo.rb +278 -0
- data/lib/tryouts.rb +405 -320
- data/try/step1_try.rb +51 -0
- data/try/step2_try.rb +59 -0
- data/try/step3_try.rb +19 -0
- data/try/step4_try.rb +6 -0
- metadata +20 -75
- data/CHANGES.txt +0 -202
- data/bin/mockout +0 -54
- data/bin/sergeant +0 -66
- data/lib/tryouts/cli/run.rb +0 -229
- data/lib/tryouts/cli.rb +0 -15
- data/lib/tryouts/drill/context.rb +0 -33
- data/lib/tryouts/drill/dream.rb +0 -57
- data/lib/tryouts/drill/reality.rb +0 -49
- data/lib/tryouts/drill/response.rb +0 -117
- data/lib/tryouts/drill/sergeant/api.rb +0 -42
- data/lib/tryouts/drill/sergeant/benchmark.rb +0 -76
- data/lib/tryouts/drill/sergeant/cli.rb +0 -66
- data/lib/tryouts/drill/sergeant/rbenchmark.rb +0 -132
- data/lib/tryouts/drill.rb +0 -224
- data/lib/tryouts/mixins.rb +0 -37
- data/lib/tryouts/orderedhash.rb +0 -199
- data/lib/tryouts/stats.rb +0 -96
- data/lib/tryouts/tryout.rb +0 -176
- data/tryouts/01_mixins_tryouts.rb +0 -23
- data/tryouts/10_syntax_tryouts.rb +0 -44
- data/tryouts/14_set_tryouts.rb +0 -26
- data/tryouts/15_dreams_tryouts.rb +0 -54
- data/tryouts/20_cli_tryouts.rb +0 -40
- data/tryouts/30_benchmark_tryouts.rb +0 -27
- data/tryouts/50_class_context_tryouts.rb +0 -33
- data/tryouts/X1_new_api_syntax.rb +0 -78
- data/tryouts/X2_new_cli_syntax.rb +0 -36
- data/tryouts/standalone_test.rb +0 -39
- data/tryouts.gemspec +0 -84
@@ -1,132 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'benchmark'
|
3
|
-
|
4
|
-
|
5
|
-
class Tryouts; class Drill; module Sergeant
|
6
|
-
|
7
|
-
# = RBenchmark
|
8
|
-
#
|
9
|
-
# This is an implementation of Better-Benchmark:
|
10
|
-
# http://github.com/Pistos/better-benchmark/
|
11
|
-
#
|
12
|
-
# NOTE: It's a work in progress and currently not functioning
|
13
|
-
#
|
14
|
-
# See also: http://www.graphpad.com/articles/interpret/Analyzing_two_groups/wilcoxon_matched_pairs.htm
|
15
|
-
#
|
16
|
-
module RBenchmark
|
17
|
-
|
18
|
-
VERSION = '0.7.0'
|
19
|
-
|
20
|
-
class ComparisonPartial
|
21
|
-
def initialize( block, options )
|
22
|
-
@block1 = block
|
23
|
-
@options = options
|
24
|
-
end
|
25
|
-
|
26
|
-
def with( &block2 )
|
27
|
-
times1 = []
|
28
|
-
times2 = []
|
29
|
-
|
30
|
-
(1..@options[ :iterations ]).each do |iteration|
|
31
|
-
if @options[ :verbose ]
|
32
|
-
$stdout.print "."; $stdout.flush
|
33
|
-
end
|
34
|
-
|
35
|
-
times1 << ::Benchmark.realtime do
|
36
|
-
@options[ :inner_iterations ].times do |i|
|
37
|
-
@block1.call( iteration )
|
38
|
-
end
|
39
|
-
end
|
40
|
-
times2 << ::Benchmark.realtime do
|
41
|
-
@options[ :inner_iterations ].times do |i|
|
42
|
-
block2.call( iteration )
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
r = RSRuby.instance
|
48
|
-
wilcox_result = r.wilcox_test( times1, times2 )
|
49
|
-
|
50
|
-
{
|
51
|
-
:results1 => {
|
52
|
-
:times => times1,
|
53
|
-
:mean => r.mean( times1 ),
|
54
|
-
:stddev => r.sd( times1 ),
|
55
|
-
},
|
56
|
-
:results2 => {
|
57
|
-
:times => times2,
|
58
|
-
:mean => r.mean( times2 ),
|
59
|
-
:stddev => r.sd( times2 ),
|
60
|
-
},
|
61
|
-
:p => wilcox_result[ 'p.value' ],
|
62
|
-
:W => wilcox_result[ 'statistic' ][ 'W' ],
|
63
|
-
:significant => (
|
64
|
-
wilcox_result[ 'p.value' ] < @options[ :required_significance ]
|
65
|
-
),
|
66
|
-
}
|
67
|
-
end
|
68
|
-
alias to with
|
69
|
-
end
|
70
|
-
|
71
|
-
# Options:
|
72
|
-
# :iterations
|
73
|
-
# The number of times to execute the pair of blocks.
|
74
|
-
# :inner_iterations
|
75
|
-
# Used to increase the time taken per iteration.
|
76
|
-
# :required_significance
|
77
|
-
# Maximum allowed p value in order to declare the results statistically significant.
|
78
|
-
# :verbose
|
79
|
-
# Whether to print a dot for each iteration (as a sort of progress meter).
|
80
|
-
#
|
81
|
-
# To use better-benchmark properly, it is important to set :iterations and
|
82
|
-
# :inner_iterations properly. There are a few things to bear in mind:
|
83
|
-
#
|
84
|
-
# (1) Do not set :iterations too high. It should normally be in the range
|
85
|
-
# of 10-20, but can be lower. Over 25 should be considered too high.
|
86
|
-
# (2) Execution time for one run of the blocks under test should not be too
|
87
|
-
# small (or else random variance will muddle the results). Aim for at least
|
88
|
-
# 1.0 seconds per iteration.
|
89
|
-
# (3) Minimize the proportion of any warmup time (and cooldown time) of one
|
90
|
-
# block run.
|
91
|
-
#
|
92
|
-
# In order to achieve these goals, you will need to tweak :inner_iterations
|
93
|
-
# based on your situation. The exact number you should use will depend on
|
94
|
-
# the strength of the hardware (CPU, RAM, disk), and the amount of work done
|
95
|
-
# by the blocks. For code blocks that execute extremely rapidly, you may
|
96
|
-
# need hundreds of thousands of :inner_iterations.
|
97
|
-
def self.compare_realtime( options = {}, &block1 )
|
98
|
-
require 'rsruby'
|
99
|
-
|
100
|
-
options[ :iterations ] ||= 20
|
101
|
-
options[ :inner_iterations ] ||= 1
|
102
|
-
options[ :required_significance ] ||= 0.01
|
103
|
-
|
104
|
-
if options[ :iterations ] > 30
|
105
|
-
warn "The number of iterations is set to #{options[ :iterations ]}. " +
|
106
|
-
"Using too many iterations may make the test results less reliable. " +
|
107
|
-
"It is recommended to increase the number of :inner_iterations instead."
|
108
|
-
end
|
109
|
-
|
110
|
-
ComparisonPartial.new( block1, options )
|
111
|
-
end
|
112
|
-
|
113
|
-
def self.report_on( result )
|
114
|
-
puts
|
115
|
-
puts( "Set 1 mean: %.3f s" % [ result[ :results1 ][ :mean ] ] )
|
116
|
-
puts( "Set 1 std dev: %.3f" % [ result[ :results1 ][ :stddev ] ] )
|
117
|
-
puts( "Set 2 mean: %.3f s" % [ result[ :results2 ][ :mean ] ] )
|
118
|
-
puts( "Set 2 std dev: %.3f" % [ result[ :results2 ][ :stddev ] ] )
|
119
|
-
puts "p.value: #{result[ :p ]}"
|
120
|
-
puts "W: #{result[ :W ]}"
|
121
|
-
puts(
|
122
|
-
"The difference (%+.1f%%) %s statistically significant." % [
|
123
|
-
( ( result[ :results2 ][ :mean ] - result[ :results1 ][ :mean ] ) / result[ :results1 ][ :mean ] ) * 100,
|
124
|
-
result[ :significant ] ? 'IS' : 'IS NOT'
|
125
|
-
]
|
126
|
-
)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
end; end; end
|
131
|
-
|
132
|
-
|
data/lib/tryouts/drill.rb
DELETED
@@ -1,224 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
class Tryouts
|
4
|
-
|
5
|
-
# = Drill
|
6
|
-
#
|
7
|
-
# This class represents a drill. A drill is single test.
|
8
|
-
#
|
9
|
-
class Drill
|
10
|
-
|
11
|
-
require 'tryouts/drill/context'
|
12
|
-
require 'tryouts/drill/response'
|
13
|
-
require 'tryouts/drill/dream'
|
14
|
-
require 'tryouts/drill/reality'
|
15
|
-
require 'tryouts/drill/sergeant/cli'
|
16
|
-
require 'tryouts/drill/sergeant/api'
|
17
|
-
require 'tryouts/drill/sergeant/benchmark'
|
18
|
-
#require 'tryouts/drill/sergeant/rbenchmark'
|
19
|
-
|
20
|
-
class NoSergeant < Tryouts::Exception; end
|
21
|
-
class UnknownFormat < Tryouts::Exception; end
|
22
|
-
|
23
|
-
# A symbol specifying the drill type. One of: :cli, :api
|
24
|
-
attr_reader :dtype
|
25
|
-
# The name of the drill. This should match the name used in the dreams file.
|
26
|
-
attr_reader :name
|
27
|
-
# A Proc object which contains the drill logic.
|
28
|
-
attr_reader :drill
|
29
|
-
# A Sergeant object which executes the drill
|
30
|
-
attr_reader :sergeant
|
31
|
-
# An Array of Dream objects (the expected output of the test)
|
32
|
-
attr_reader :dreams
|
33
|
-
# A Reality object (the actual output of the test)
|
34
|
-
attr_reader :reality
|
35
|
-
|
36
|
-
@@valid_dtypes = [:api, :cli, :benchmark]
|
37
|
-
|
38
|
-
# * +name+ The display name of this drill
|
39
|
-
# * +dtype+ A Symbol representing the drill type. One of: :api, :benchmark
|
40
|
-
# * +args+ These are dependent on the drill type. See the Sergeant classes
|
41
|
-
# * +&drill+ The body of the drill. The return value of this block
|
42
|
-
# is compared to the exepected output of the dreams.
|
43
|
-
#
|
44
|
-
# The DSL syntax:
|
45
|
-
# * dream OUTPUT
|
46
|
-
# * dream FORMAT, OUTPUT
|
47
|
-
# * dream FORMAT, OUTPUT, REPS (benchmark only)
|
48
|
-
#
|
49
|
-
def initialize(name, dtype, *args, &drill)
|
50
|
-
@name, @dtype, @drill, @skip = name, dtype, drill, false
|
51
|
-
@dreams = []
|
52
|
-
|
53
|
-
# We create a default empty reality but if the drill runs correctly
|
54
|
-
# this reality gets replaced with the return value from the drill.
|
55
|
-
@reality = Tryouts::Drill::Reality.new
|
56
|
-
|
57
|
-
case @dtype
|
58
|
-
when :cli
|
59
|
-
# For CLI drills, a block takes precedence over inline args.
|
60
|
-
# A block will contain multiple shell commands (see Rye::Box#batch)
|
61
|
-
args = [] if dtype == :cli && drill.is_a?(Proc)
|
62
|
-
@sergeant = Tryouts::Drill::Sergeant::CLI.new *args
|
63
|
-
when :api
|
64
|
-
default_output = drill.nil? ? args.shift : nil
|
65
|
-
@sergeant = Tryouts::Drill::Sergeant::API.new default_output
|
66
|
-
unless args.empty?
|
67
|
-
if args.size == 1
|
68
|
-
dream_output, format = args.first, nil
|
69
|
-
else
|
70
|
-
dream_output, format = args[1], args[0]
|
71
|
-
end
|
72
|
-
@dreams << Tryouts::Drill::Dream.new(dream_output, format)
|
73
|
-
end
|
74
|
-
when :benchmark
|
75
|
-
if args.size == 1
|
76
|
-
reps = args.first
|
77
|
-
else
|
78
|
-
dream_output, format, reps = args[1], args[0], args[2]
|
79
|
-
end
|
80
|
-
@sergeant = Tryouts::Drill::Sergeant::Benchmark.new reps
|
81
|
-
@dreams << Tryouts::Drill::Dream.new(Hash, :class)
|
82
|
-
unless dream_output.nil?
|
83
|
-
@dreams << Tryouts::Drill::Dream.new(dream_output, format)
|
84
|
-
end
|
85
|
-
when :skip
|
86
|
-
@skip = true
|
87
|
-
else
|
88
|
-
raise NoSergeant, "Weird drill sergeant: #{@dtype}"
|
89
|
-
end
|
90
|
-
@clr = :red
|
91
|
-
|
92
|
-
|
93
|
-
end
|
94
|
-
|
95
|
-
def self.valid_dtypes; @@valid_dtypes; end
|
96
|
-
def self.valid_dtype?(t); @@valid_dtypes.member?(t); end
|
97
|
-
|
98
|
-
def skip?; @skip; end
|
99
|
-
|
100
|
-
def run(context=nil)
|
101
|
-
unless @dreams.empty?
|
102
|
-
@dreams.each { |d| d.execute_output_block }
|
103
|
-
end
|
104
|
-
begin
|
105
|
-
@reality = @sergeant.run @drill, context
|
106
|
-
# Store the stash from the drill block
|
107
|
-
@reality.stash = context.stash if context.respond_to? :stash
|
108
|
-
# If the drill block returned true we assume success if there's no dream
|
109
|
-
if @dreams.empty? && @reality.output == true
|
110
|
-
@dreams << Tryouts::Drill::Dream.new
|
111
|
-
@dreams.first.output = true
|
112
|
-
end
|
113
|
-
rescue => ex
|
114
|
-
@reality.ecode, @reality.etype = -2, ex.class
|
115
|
-
@reality.error, @reality.trace = ex.message, ex.backtrace
|
116
|
-
end
|
117
|
-
self.success?
|
118
|
-
end
|
119
|
-
|
120
|
-
def flag
|
121
|
-
if skip?
|
122
|
-
"SKIP"
|
123
|
-
elsif success?
|
124
|
-
"PASS".color(@clr).bright
|
125
|
-
else
|
126
|
-
note = @dreams.empty? ? '[nodream]' : ''
|
127
|
-
"FAIL #{note}".color(@clr).bright
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
def info
|
132
|
-
out = StringIO.new
|
133
|
-
if Tryouts.verbose > 0
|
134
|
-
if @dtype == :benchmark
|
135
|
-
unless @reality.output.nil?
|
136
|
-
Sergeant::Benchmark.fields.each do |f|
|
137
|
-
s = @reality.output[f]
|
138
|
-
ar = [s.name, s.mean, s.min, s.max, s.sdev, s.sum]
|
139
|
-
pa = '%6s: %.4f (min:%.4f max:%.4f sdev:%.4f sum:%.4f)'.color(@clr)
|
140
|
-
out.puts pa % ar
|
141
|
-
end
|
142
|
-
ar = ['', @reality.output[:rtotal].mean]
|
143
|
-
out.puts '%8s%3.4f (run time)'.color(@clr) % ar
|
144
|
-
end
|
145
|
-
elsif @dtype == :cli
|
146
|
-
out.puts '%6s%s'.color(@clr) % ['', @reality.command]
|
147
|
-
output = @reality.output
|
148
|
-
output = output.join($/ + ' '*6) if output.kind_of?(Array)
|
149
|
-
out.puts '%6s%s'.color(@clr) % ['', output]
|
150
|
-
else
|
151
|
-
out.puts '%6s%s'.color(@clr) % ['', @reality.output.inspect]
|
152
|
-
end
|
153
|
-
unless @reality.stash.empty?
|
154
|
-
@reality.stash.each_pair do |n,v|
|
155
|
-
out.puts '%18s: %s'.color(@clr) % [n,v.inspect]
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
if Tryouts.verbose > 1
|
160
|
-
|
161
|
-
@dreams.each do |dream|
|
162
|
-
if dream != @reality
|
163
|
-
out.puts '%6s%s'.color(:red) % ['', dream.test_to_string(@reality)]
|
164
|
-
else
|
165
|
-
out.puts '%6s%s'.color(:green) % ["", dream.test_to_string(@reality)]
|
166
|
-
end
|
167
|
-
end
|
168
|
-
out.puts
|
169
|
-
|
170
|
-
end
|
171
|
-
out.rewind
|
172
|
-
out.read
|
173
|
-
end
|
174
|
-
|
175
|
-
def report
|
176
|
-
return if skip?
|
177
|
-
out = StringIO.new
|
178
|
-
|
179
|
-
out.puts '%12s'.color(:red) % '[nodream]' if @dreams.empty?
|
180
|
-
|
181
|
-
@dreams.each do |dream|
|
182
|
-
next if dream == reality #? :normal : :red
|
183
|
-
out.puts '%12s: %s'.color(@clr) % ["failed", dream.test_to_string(@reality)]
|
184
|
-
out.puts '%12s: %s' % ["drill", @reality.comparison_value(dream).inspect]
|
185
|
-
out.puts '%12s: %s' % ["dream", dream.comparison_value.inspect]
|
186
|
-
out.puts
|
187
|
-
end
|
188
|
-
|
189
|
-
unless @reality.error.nil?
|
190
|
-
out.puts '%14s: %s' % [@reality.etype, @reality.error.to_s.split($/).join($/ + ' '*16)]
|
191
|
-
end
|
192
|
-
unless @reality.trace.nil?
|
193
|
-
trace = Tryouts.verbose > 1 ? @reality.trace : [@reality.trace.first]
|
194
|
-
out.puts '%14s %s' % ['', trace.join($/ + ' '*16)]
|
195
|
-
out.puts
|
196
|
-
end
|
197
|
-
|
198
|
-
out.rewind
|
199
|
-
out.read
|
200
|
-
end
|
201
|
-
|
202
|
-
def has_error?
|
203
|
-
!@reality.error.nil?
|
204
|
-
end
|
205
|
-
|
206
|
-
def success?
|
207
|
-
return false if @dreams.empty? && @reality.output != true
|
208
|
-
begin
|
209
|
-
@dreams.each { |d| return false unless d == @reality }
|
210
|
-
rescue => ex
|
211
|
-
puts ex.message, ex.backtrace if Tryouts.debug?
|
212
|
-
return false
|
213
|
-
end
|
214
|
-
@clr = :green
|
215
|
-
true
|
216
|
-
end
|
217
|
-
|
218
|
-
|
219
|
-
def add_dream(d); @dreams << d; end
|
220
|
-
def add_dreams(*d); @dreams += d; end
|
221
|
-
|
222
|
-
private
|
223
|
-
|
224
|
-
end; end
|
data/lib/tryouts/mixins.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
|
2
|
-
class Hash
|
3
|
-
|
4
|
-
# A depth-first look to find the deepest point in the Hash.
|
5
|
-
# The top level Hash is counted in the total so the final
|
6
|
-
# number is the depth of its children + 1. An example:
|
7
|
-
#
|
8
|
-
# ahash = { :level1 => { :level2 => {} } }
|
9
|
-
# ahash.deepest_point # => 3
|
10
|
-
#
|
11
|
-
def deepest_point(h=self, steps=0)
|
12
|
-
if h.is_a?(Hash)
|
13
|
-
steps += 1
|
14
|
-
h.each_pair do |n,possible_h|
|
15
|
-
ret = deepest_point(possible_h, steps)
|
16
|
-
steps = ret if steps < ret
|
17
|
-
end
|
18
|
-
else
|
19
|
-
return 0
|
20
|
-
end
|
21
|
-
steps
|
22
|
-
end
|
23
|
-
|
24
|
-
unless method_defined?(:last)
|
25
|
-
# Ruby 1.9 doesn't have a Hash#last (but Tryouts::OrderedHash does).
|
26
|
-
# It's used in Tryouts to return the most recently added instance of
|
27
|
-
# Tryouts to @@instances.
|
28
|
-
#
|
29
|
-
# NOTE: This method is defined only when Hash.method_defined?(:last)
|
30
|
-
# returns false.
|
31
|
-
def last
|
32
|
-
self[ self.keys.last ]
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
|
data/lib/tryouts/orderedhash.rb
DELETED
@@ -1,199 +0,0 @@
|
|
1
|
-
# AUTHOR
|
2
|
-
# jan molic /mig/at/1984/dot/cz/
|
3
|
-
#
|
4
|
-
# DESCRIPTION
|
5
|
-
# Hash with preserved order and some array-like extensions
|
6
|
-
# Public domain.
|
7
|
-
#
|
8
|
-
# THANKS
|
9
|
-
# Andrew Johnson for his suggestions and fixes of Hash[],
|
10
|
-
# merge, to_a, inspect and shift
|
11
|
-
class Tryouts::OrderedHash < ::Hash
|
12
|
-
attr_accessor :order
|
13
|
-
|
14
|
-
class << self
|
15
|
-
def [] *args
|
16
|
-
hsh = Tryouts::OrderedHash.new
|
17
|
-
if Hash === args[0]
|
18
|
-
hsh.replace args[0]
|
19
|
-
elsif (args.size % 2) != 0
|
20
|
-
raise ArgumentError, "odd number of elements for Hash"
|
21
|
-
else
|
22
|
-
0.step(args.size - 1, 2) do |a|
|
23
|
-
b = a + 1
|
24
|
-
hsh[args[a]] = args[b]
|
25
|
-
end
|
26
|
-
end
|
27
|
-
hsh
|
28
|
-
end
|
29
|
-
end
|
30
|
-
def initialize(*a, &b)
|
31
|
-
super
|
32
|
-
@order = []
|
33
|
-
end
|
34
|
-
def store_only a,b
|
35
|
-
store a,b
|
36
|
-
end
|
37
|
-
alias orig_store store
|
38
|
-
def store a,b
|
39
|
-
@order.push a unless has_key? a
|
40
|
-
super a,b
|
41
|
-
end
|
42
|
-
alias []= store
|
43
|
-
def == hsh2
|
44
|
-
return false if @order != hsh2.order
|
45
|
-
super hsh2
|
46
|
-
end
|
47
|
-
def clear
|
48
|
-
@order = []
|
49
|
-
super
|
50
|
-
end
|
51
|
-
def delete key
|
52
|
-
@order.delete key
|
53
|
-
super
|
54
|
-
end
|
55
|
-
def each_key
|
56
|
-
@order.each { |k| yield k }
|
57
|
-
self
|
58
|
-
end
|
59
|
-
def each_value
|
60
|
-
@order.each { |k| yield self[k] }
|
61
|
-
self
|
62
|
-
end
|
63
|
-
def each
|
64
|
-
@order.each { |k| yield k,self[k] }
|
65
|
-
self
|
66
|
-
end
|
67
|
-
alias each_pair each
|
68
|
-
def delete_if
|
69
|
-
@order.clone.each { |k|
|
70
|
-
delete k if yield(k)
|
71
|
-
}
|
72
|
-
self
|
73
|
-
end
|
74
|
-
def values
|
75
|
-
ary = []
|
76
|
-
@order.each { |k| ary.push self[k] }
|
77
|
-
ary
|
78
|
-
end
|
79
|
-
def keys
|
80
|
-
@order
|
81
|
-
end
|
82
|
-
def first
|
83
|
-
{@order.first => self[@order.first]}
|
84
|
-
end
|
85
|
-
def last
|
86
|
-
{@order.last => self[@order.last]}
|
87
|
-
end
|
88
|
-
def invert
|
89
|
-
hsh2 = Hash.new
|
90
|
-
@order.each { |k| hsh2[self[k]] = k }
|
91
|
-
hsh2
|
92
|
-
end
|
93
|
-
def reject &block
|
94
|
-
self.dup.delete_if &block
|
95
|
-
end
|
96
|
-
def reject! &block
|
97
|
-
hsh2 = reject &block
|
98
|
-
self == hsh2 ? nil : hsh2
|
99
|
-
end
|
100
|
-
def replace hsh2
|
101
|
-
@order = hsh2.keys
|
102
|
-
super hsh2
|
103
|
-
end
|
104
|
-
def shift
|
105
|
-
key = @order.first
|
106
|
-
key ? [key,delete(key)] : super
|
107
|
-
end
|
108
|
-
def unshift k,v
|
109
|
-
unless self.include? k
|
110
|
-
@order.unshift k
|
111
|
-
orig_store(k,v)
|
112
|
-
true
|
113
|
-
else
|
114
|
-
false
|
115
|
-
end
|
116
|
-
end
|
117
|
-
def push k,v
|
118
|
-
unless self.include? k
|
119
|
-
@order.push k
|
120
|
-
orig_store(k,v)
|
121
|
-
true
|
122
|
-
else
|
123
|
-
false
|
124
|
-
end
|
125
|
-
end
|
126
|
-
def pop
|
127
|
-
key = @order.last
|
128
|
-
key ? [key,delete(key)] : nil
|
129
|
-
end
|
130
|
-
def to_a
|
131
|
-
ary = []
|
132
|
-
each { |k,v| ary << [k,v] }
|
133
|
-
ary
|
134
|
-
end
|
135
|
-
def to_s
|
136
|
-
self.to_a.to_s
|
137
|
-
end
|
138
|
-
def inspect
|
139
|
-
ary = []
|
140
|
-
each {|k,v| ary << k.inspect + "=>" + v.inspect}
|
141
|
-
'{' + ary.join(", ") + '}'
|
142
|
-
end
|
143
|
-
def update hsh2
|
144
|
-
hsh2.each { |k,v| self[k] = v }
|
145
|
-
self
|
146
|
-
end
|
147
|
-
alias :merge! update
|
148
|
-
def merge hsh2
|
149
|
-
##self.dup update(hsh2) ## 2009-05-12 -- delano
|
150
|
-
update hsh2 ## dup doesn't take an argument
|
151
|
-
## and there's no need for it here
|
152
|
-
end
|
153
|
-
def select
|
154
|
-
ary = []
|
155
|
-
each { |k,v| ary << [k,v] if yield k,v }
|
156
|
-
ary
|
157
|
-
end
|
158
|
-
def class
|
159
|
-
Hash
|
160
|
-
end
|
161
|
-
def __class__
|
162
|
-
Tryouts::OrderedHash
|
163
|
-
end
|
164
|
-
|
165
|
-
attr_accessor "to_yaml_style"
|
166
|
-
def yaml_inline= bool
|
167
|
-
if respond_to?("to_yaml_style")
|
168
|
-
self.to_yaml_style = :inline
|
169
|
-
else
|
170
|
-
unless defined? @__yaml_inline_meth
|
171
|
-
@__yaml_inline_meth =
|
172
|
-
lambda {|opts|
|
173
|
-
YAML::quick_emit(object_id, opts) {|emitter|
|
174
|
-
emitter << '{ ' << map{|kv| kv.join ': '}.join(', ') << ' }'
|
175
|
-
}
|
176
|
-
}
|
177
|
-
class << self
|
178
|
-
def to_yaml opts = {}
|
179
|
-
begin
|
180
|
-
@__yaml_inline ? @__yaml_inline_meth[ opts ] : super
|
181
|
-
rescue
|
182
|
-
@to_yaml_style = :inline
|
183
|
-
super
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
189
|
-
@__yaml_inline = bool
|
190
|
-
end
|
191
|
-
def yaml_inline!() self.yaml_inline = true end
|
192
|
-
|
193
|
-
def each_with_index
|
194
|
-
@order.each_with_index { |k, index| yield k, self[k], index }
|
195
|
-
self
|
196
|
-
end
|
197
|
-
end # class Tryouts::OrderedHash
|
198
|
-
|
199
|
-
|
data/lib/tryouts/stats.rb
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
# Copyright (c) 2005 Zed A. Shaw
|
2
|
-
# You can redistribute it and/or modify it under the same terms as Ruby.
|
3
|
-
#
|
4
|
-
# Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
|
5
|
-
# for more information.
|
6
|
-
|
7
|
-
# Stolen from:
|
8
|
-
# http://mongrel.rubyforge.org/browser/trunk/lib/mongrel/stats.rb
|
9
|
-
#
|
10
|
-
# A very simple little class for doing some basic fast statistics sampling.
|
11
|
-
# You feed it either samples of numeric data you want measured or you call
|
12
|
-
# Stats.tick to get it to add a time delta between the last time you called it.
|
13
|
-
# When you're done either call sum, sumsq, n, min, max, mean or sd to get
|
14
|
-
# the information. The other option is to just call dump and see everything.
|
15
|
-
#
|
16
|
-
# It does all of this very fast and doesn't take up any memory since the samples
|
17
|
-
# are not stored but instead all the values are calculated on the fly.
|
18
|
-
class Tryouts
|
19
|
-
class Stats
|
20
|
-
attr_reader :sum, :sumsq, :n, :min, :max, :name
|
21
|
-
|
22
|
-
def initialize(name=:unknown)
|
23
|
-
@name = name
|
24
|
-
reset
|
25
|
-
end
|
26
|
-
|
27
|
-
# Resets the internal counters so you can start sampling again.
|
28
|
-
def reset
|
29
|
-
@sum = 0.0
|
30
|
-
@sumsq = 0.0
|
31
|
-
@last_time = Time.new
|
32
|
-
@n = 0.0
|
33
|
-
@min = 0.0
|
34
|
-
@max = 0.0
|
35
|
-
end
|
36
|
-
|
37
|
-
def samples; @n; end
|
38
|
-
|
39
|
-
# Adds a sampling to the calculations.
|
40
|
-
def sample(s)
|
41
|
-
@sum += s
|
42
|
-
@sumsq += s * s
|
43
|
-
if @n == 0
|
44
|
-
@min = @max = s
|
45
|
-
else
|
46
|
-
@min = s if @min > s
|
47
|
-
@max = s if @max < s
|
48
|
-
end
|
49
|
-
(@n+=1).to_f
|
50
|
-
end
|
51
|
-
|
52
|
-
# Dump this Stats object with an optional additional message.
|
53
|
-
def dump(msg = "", out=STDERR)
|
54
|
-
out.puts "#{msg}: #{self.to_s}"
|
55
|
-
end
|
56
|
-
|
57
|
-
# Returns a common display (used by dump)
|
58
|
-
def to_s
|
59
|
-
"[#{@name}]: SUM=%0.4f, SUMSQ=%0.4f, N=%0.4f, MEAN=%0.4f, SD=%0.4f, MIN=%0.4f, MAX=%0.4f" % [@sum, @sumsq, @n, mean, sd, @min, @max]
|
60
|
-
end
|
61
|
-
|
62
|
-
|
63
|
-
# Calculates and returns the mean for the data passed so far.
|
64
|
-
def mean
|
65
|
-
@sum / @n
|
66
|
-
end
|
67
|
-
|
68
|
-
# Calculates the standard deviation of the data so far.
|
69
|
-
def sdev
|
70
|
-
# (sqrt( ((s).sumsq - ( (s).sum * (s).sum / (s).n)) / ((s).n-1) ))
|
71
|
-
begin
|
72
|
-
Math.sqrt( (@sumsq - ( @sum * @sum / @n)) / (@n-1) ).to_f
|
73
|
-
rescue Errno::EDOM
|
74
|
-
0.0
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
# Adds a time delta between now and the last time you called this. This
|
80
|
-
# will give you the average time between two activities.
|
81
|
-
#
|
82
|
-
# An example is:
|
83
|
-
#
|
84
|
-
# t = Stats.new("do_stuff")
|
85
|
-
# 10000.times { do_stuff(); t.tick }
|
86
|
-
# t.dump("time")
|
87
|
-
#
|
88
|
-
def tick
|
89
|
-
now = Time.now
|
90
|
-
sample(now - @last_time)
|
91
|
-
@last_time = now
|
92
|
-
end
|
93
|
-
|
94
|
-
|
95
|
-
end
|
96
|
-
end
|