scout-gear 9.1.0 → 10.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +3 -3
  3. data/Rakefile +1 -2
  4. data/VERSION +1 -1
  5. data/lib/scout/offsite/exceptions.rb +9 -0
  6. data/lib/scout/offsite/ssh.rb +1 -0
  7. data/lib/scout/semaphore.rb +2 -0
  8. data/lib/scout/tsv/open.rb +1 -1
  9. data/lib/scout/tsv/parser.rb +1 -1
  10. data/lib/scout/tsv/persist/adapter.rb +2 -2
  11. data/lib/scout/tsv/persist.rb +1 -0
  12. data/lib/scout/tsv.rb +1 -1
  13. data/lib/scout/work_queue/exceptions.rb +18 -0
  14. data/lib/scout/work_queue.rb +1 -0
  15. data/lib/scout/workflow/definition.rb +1 -1
  16. data/lib/scout/workflow/step/config.rb +1 -1
  17. data/lib/scout/workflow/step.rb +2 -2
  18. data/lib/scout/workflow/task/inputs.rb +1 -1
  19. data/lib/scout/workflow/task.rb +2 -2
  20. data/lib/scout/workflow.rb +2 -2
  21. data/lib/scout-gear.rb +1 -10
  22. data/scout-gear.gemspec +8 -98
  23. data/test/scout/workflow/task/test_inputs.rb +0 -4
  24. metadata +7 -110
  25. data/lib/scout/cmd.rb +0 -347
  26. data/lib/scout/concurrent_stream.rb +0 -284
  27. data/lib/scout/config.rb +0 -168
  28. data/lib/scout/exceptions.rb +0 -151
  29. data/lib/scout/indiferent_hash/case_insensitive.rb +0 -30
  30. data/lib/scout/indiferent_hash/options.rb +0 -115
  31. data/lib/scout/indiferent_hash.rb +0 -96
  32. data/lib/scout/log/color.rb +0 -224
  33. data/lib/scout/log/color_class.rb +0 -269
  34. data/lib/scout/log/fingerprint.rb +0 -69
  35. data/lib/scout/log/progress/report.rb +0 -244
  36. data/lib/scout/log/progress/util.rb +0 -173
  37. data/lib/scout/log/progress.rb +0 -106
  38. data/lib/scout/log/trap.rb +0 -107
  39. data/lib/scout/log.rb +0 -441
  40. data/lib/scout/meta_extension.rb +0 -100
  41. data/lib/scout/misc/digest.rb +0 -63
  42. data/lib/scout/misc/filesystem.rb +0 -25
  43. data/lib/scout/misc/format.rb +0 -255
  44. data/lib/scout/misc/helper.rb +0 -31
  45. data/lib/scout/misc/insist.rb +0 -56
  46. data/lib/scout/misc/monitor.rb +0 -66
  47. data/lib/scout/misc/system.rb +0 -73
  48. data/lib/scout/misc.rb +0 -10
  49. data/lib/scout/named_array.rb +0 -138
  50. data/lib/scout/open/lock/lockfile.rb +0 -587
  51. data/lib/scout/open/lock.rb +0 -68
  52. data/lib/scout/open/remote.rb +0 -135
  53. data/lib/scout/open/stream.rb +0 -491
  54. data/lib/scout/open/util.rb +0 -244
  55. data/lib/scout/open.rb +0 -170
  56. data/lib/scout/path/find.rb +0 -204
  57. data/lib/scout/path/tmpfile.rb +0 -8
  58. data/lib/scout/path/util.rb +0 -127
  59. data/lib/scout/path.rb +0 -51
  60. data/lib/scout/persist/open.rb +0 -17
  61. data/lib/scout/persist/path.rb +0 -15
  62. data/lib/scout/persist/serialize.rb +0 -157
  63. data/lib/scout/persist.rb +0 -104
  64. data/lib/scout/resource/open.rb +0 -8
  65. data/lib/scout/resource/path.rb +0 -80
  66. data/lib/scout/resource/produce/rake.rb +0 -69
  67. data/lib/scout/resource/produce.rb +0 -151
  68. data/lib/scout/resource/scout.rb +0 -3
  69. data/lib/scout/resource/software.rb +0 -178
  70. data/lib/scout/resource/util.rb +0 -59
  71. data/lib/scout/resource.rb +0 -41
  72. data/lib/scout/simple_opt/accessor.rb +0 -54
  73. data/lib/scout/simple_opt/doc.rb +0 -126
  74. data/lib/scout/simple_opt/get.rb +0 -57
  75. data/lib/scout/simple_opt/parse.rb +0 -67
  76. data/lib/scout/simple_opt/setup.rb +0 -26
  77. data/lib/scout/simple_opt.rb +0 -5
  78. data/lib/scout/tmpfile.rb +0 -129
  79. data/test/scout/indiferent_hash/test_case_insensitive.rb +0 -16
  80. data/test/scout/indiferent_hash/test_options.rb +0 -46
  81. data/test/scout/log/test_progress.rb +0 -108
  82. data/test/scout/misc/test_digest.rb +0 -30
  83. data/test/scout/misc/test_filesystem.rb +0 -30
  84. data/test/scout/misc/test_insist.rb +0 -13
  85. data/test/scout/misc/test_system.rb +0 -21
  86. data/test/scout/open/test_lock.rb +0 -52
  87. data/test/scout/open/test_remote.rb +0 -25
  88. data/test/scout/open/test_stream.rb +0 -676
  89. data/test/scout/open/test_util.rb +0 -73
  90. data/test/scout/path/test_find.rb +0 -119
  91. data/test/scout/path/test_util.rb +0 -22
  92. data/test/scout/persist/test_open.rb +0 -37
  93. data/test/scout/persist/test_path.rb +0 -37
  94. data/test/scout/persist/test_serialize.rb +0 -114
  95. data/test/scout/resource/test_path.rb +0 -46
  96. data/test/scout/resource/test_produce.rb +0 -92
  97. data/test/scout/resource/test_software.rb +0 -24
  98. data/test/scout/resource/test_util.rb +0 -36
  99. data/test/scout/simple_opt/test_doc.rb +0 -16
  100. data/test/scout/simple_opt/test_get.rb +0 -11
  101. data/test/scout/simple_opt/test_parse.rb +0 -10
  102. data/test/scout/simple_opt/test_setup.rb +0 -77
  103. data/test/scout/test_cmd.rb +0 -85
  104. data/test/scout/test_concurrent_stream.rb +0 -29
  105. data/test/scout/test_config.rb +0 -66
  106. data/test/scout/test_indiferent_hash.rb +0 -26
  107. data/test/scout/test_log.rb +0 -32
  108. data/test/scout/test_meta_extension.rb +0 -80
  109. data/test/scout/test_misc.rb +0 -6
  110. data/test/scout/test_named_array.rb +0 -43
  111. data/test/scout/test_open.rb +0 -146
  112. data/test/scout/test_path.rb +0 -54
  113. data/test/scout/test_persist.rb +0 -186
  114. data/test/scout/test_resource.rb +0 -26
  115. data/test/scout/test_tmpfile.rb +0 -53
  116. /data/test/scout/{log/test_color.rb → test_offsite.rb} +0 -0
@@ -1,224 +0,0 @@
1
- require_relative 'color_class'
2
- require_relative '../indiferent_hash'
3
-
4
- require 'term/ansicolor'
5
-
6
- module Colorize
7
- def self.colors=(colors)
8
- @colors = colors
9
- end
10
-
11
- def self.colors
12
- @colors ||= IndiferentHash.setup(Hash[<<-EOF.split("\n").collect{|l| l.split(" ")}])
13
- green #00cd00
14
- red #cd0000
15
- yellow #ffd700
16
- blue #0000cd
17
- path blue
18
- EOF
19
- end
20
-
21
- def self.diverging_colors=(colors)
22
- @diverging_colors = colors
23
- end
24
-
25
- def self.diverging_colors
26
- @diverging_colors ||=<<~EOF.split("\n")
27
- #a6cee3
28
- #1f78b4
29
- #b2df8a
30
- #33a02c
31
- #fb9a99
32
- #e31a1c
33
- #fdbf6f
34
- #ff7f00
35
- #cab2d6
36
- #6a3d9a
37
- #ffff99
38
- #b15928
39
- EOF
40
- end
41
-
42
- def self.from_name(color)
43
- return color if color =~ /^#?[0-9A-F]+$/i
44
- return colors[color.to_s] if colors.include?(color.to_s)
45
-
46
- case color.to_s
47
- when "white"
48
- '#000'
49
- when "black"
50
- '#fff'
51
- when 'green'
52
- colors["green3"]
53
- when 'red'
54
- colors["red3"]
55
- when 'yellow'
56
- colors["gold1"]
57
- when 'blue'
58
- colors["RoyalBlue"]
59
- else
60
- colors[color.to_s] || color.to_s
61
- end
62
- end
63
-
64
- def self.continuous(array, start = "#40324F", eend = "#EABD5D", percent = false)
65
- start_color = Color.new from_name(start)
66
- end_color = Color.new from_name(eend)
67
-
68
- if percent
69
- array = array.collect{|v| n = v.to_f; n = n > 100 ? 100 : n; n < 0.001 ? 0.001 : n}
70
- else
71
- array = array.collect{|v| v.to_f }
72
- end
73
- max = array.max
74
- min = array.min
75
- range = max - min
76
- array.collect do |v|
77
- ratio = (v.to_f-min) / range
78
- start_color.blend end_color, ratio
79
- end
80
- end
81
-
82
- def self.gradient(array, value, start = :green, eend = :red, percent = false)
83
- index = array.index value
84
- colors = continuous(array, start, eend, percent)
85
- colors[index]
86
- end
87
-
88
- def self.rank_gradient(array, value, start = :green, eend = :red, percent = false)
89
- index = array.index value
90
- sorted = array.sort
91
- array = array.collect{|e| sorted.index e}
92
- colors = continuous(array, start, eend, percent)
93
- colors[index]
94
- end
95
-
96
-
97
- def self.distinct(array)
98
- colors = diverging_colors.collect{|c| Color.new c }
99
-
100
- num = array.uniq.length
101
- times = num / 12
102
-
103
- all_colors = colors.dup
104
- factor = 0.3 / times
105
- times.times do
106
- all_colors.concat colors.collect{|n| n.darken(factor) }
107
- end
108
-
109
- value_color = Hash[*array.uniq.zip(all_colors).flatten]
110
-
111
- value_color.values_at(*array)
112
- end
113
-
114
- def self.tsv(tsv, options = {})
115
- values = tsv.values.flatten
116
- if Numeric === values.first or (values.first.to_f != 0 and values[0] != "0" and values[0] != "0.0")
117
- value_colors = IndiferentHash.process_to_hash(values){continuous(values)}
118
- else
119
- value_colors = IndiferentHash.process_to_hash(values){distinct(values)}
120
- end
121
-
122
- if tsv.type == :single
123
- Hash[*tsv.keys.zip(value_colors.values_at(*values)).flatten]
124
- else
125
- Hash[*tsv.keys.zip(values.collect{|vs| value_colors.values_at(*vs)}).flatten]
126
- end
127
- end
128
- end
129
-
130
- module Log
131
- extend Term::ANSIColor
132
-
133
- class << self
134
- attr_accessor :nocolor
135
- end
136
-
137
- self.nocolor = ENV["SCOUT_NOCOLOR"] == 'true'
138
-
139
- WHITE, DARK, GREEN, YELLOW, RED = Color::SOLARIZED.values_at :base0, :base00, :green, :yellow, :magenta
140
-
141
- SEVERITY_COLOR = [reset, cyan, green, magenta, blue, yellow, red] #.collect{|e| "\033[#{e}"}
142
- CONCEPT_COLORS = IndiferentHash.setup({
143
- :title => magenta,
144
- :path => blue,
145
- :input => cyan,
146
- :value => green,
147
- :integer => green,
148
- :negative => red,
149
- :float => green,
150
- :waiting => yellow,
151
- :started => cyan,
152
- :start => cyan,
153
- :done => green,
154
- :error => red,
155
- :time => cyan,
156
- :task => yellow,
157
- :workflow => yellow,
158
- })
159
- HIGHLIGHT = "\033[1m"
160
-
161
- def self.uncolor(str)
162
- "" << Term::ANSIColor.uncolor(str)
163
- end
164
-
165
- def self.reset_color
166
- reset
167
- end
168
-
169
- def self.color(color, str = nil, reset = false)
170
- return str.dup || "" if nocolor
171
-
172
- if (color == :integer || color == :float) && Numeric === str
173
- color = if str < 0
174
- :red
175
- elsif str > 1
176
- :cyan
177
- else
178
- :green
179
- end
180
- end
181
-
182
- if color == :status
183
- color = case str.to_sym
184
- when :done
185
- :green
186
- when :error, :aborted
187
- :red
188
- when :waiting, :queued
189
- :yellow
190
- when :started, :streamming
191
- :cyan
192
- when :start
193
- :title
194
- else
195
- :cyan
196
- end
197
- end
198
-
199
- color = SEVERITY_COLOR[color] if Integer === color
200
- color = CONCEPT_COLORS[color] if CONCEPT_COLORS.include?(color)
201
- color = Term::ANSIColor.send(color) if Symbol === color and Term::ANSIColor.respond_to?(color)
202
-
203
- str = str.to_s unless str.nil?
204
- return str if Symbol === color
205
- color_str = reset ? Term::ANSIColor.reset : ""
206
- color_str << color
207
- if str.nil?
208
- color_str
209
- else
210
- color_str + str.to_s + Term::ANSIColor.reset
211
- end
212
- end
213
-
214
- def self.highlight(str = nil)
215
- if str.nil?
216
- return "" if nocolor
217
- HIGHLIGHT
218
- else
219
- return str if nocolor
220
- HIGHLIGHT + str + color(0)
221
- end
222
- end
223
-
224
- end
@@ -1,269 +0,0 @@
1
- # Copyright (c) 2007 McClain Looney
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
20
-
21
-
22
- # Implements a color (r,g,b + a) with conversion to/from web format (eg #aabbcc), and
23
- # with a number of utilities to lighten, darken and blend values.
24
- class Color
25
-
26
- attr_reader :r, :g, :b, :a
27
-
28
- # Table for conversion to hex
29
- HEXVAL = (('0'..'9').to_a).concat(('A'..'F').to_a).freeze
30
- # Default value for #darken, #lighten etc.
31
- BRIGHTNESS_DEFAULT = 0.2
32
-
33
- SOLARIZED = {
34
- :base03 => '#002b36',
35
- :base02 => '#073642',
36
- :base01 => '#586e75',
37
- :base00 => '#657b83',
38
- :base0 => '#839496',
39
- :base1 => '#93a1a1',
40
- :base2 => '#eee8d5',
41
- :base3 => '#fdf6e3',
42
- :yellow => '#b58900',
43
- :orange => '#cb4b16',
44
- :red => '#dc322f',
45
- :magenta => '#d33682',
46
- :violet => '#6c71c4',
47
- :blue => '#268bd2',
48
- :cyan => '#2aa198',
49
- :green => '#859900',
50
- }
51
-
52
- # Constructor. Inits to white (#FFFFFF) by default, or accepts any params
53
- # supported by #parse.
54
- def initialize(*args)
55
- @r = 255
56
- @g = 255
57
- @b = 255
58
- @a = 255
59
-
60
- if args.size.between?(3,4)
61
- self.r = args[0]
62
- self.g = args[1]
63
- self.b = args[2]
64
- self.a = args[3] if args[3]
65
- else
66
- set(*args)
67
- end
68
- end
69
-
70
- # All-purpose setter - pass in another Color, '#000000', rgb vals... whatever
71
- def set(*args)
72
- val = Color.parse(*args)
73
- unless val.nil?
74
- self.r = val.r
75
- self.g = val.g
76
- self.b = val.b
77
- self.a = val.a
78
- end
79
- self
80
- end
81
-
82
- # Test for equality, accepts string vals as well, eg Color.new('aaa') == '#AAAAAA' => true
83
- def ==(val)
84
- val = Color.parse(val)
85
- return false if val.nil?
86
- return r == val.r && g == val.g && b == val.b && a == val.a
87
- end
88
-
89
- # Setters for individual channels - take 0-255 or '00'-'FF' values
90
- def r=(val); @r = from_hex(val); end
91
- def g=(val); @g = from_hex(val); end
92
- def b=(val); @b = from_hex(val); end
93
- def a=(val); @a = from_hex(val); end
94
-
95
- # Attempt to read in a string and parse it into values
96
- def self.parse(*args)
97
- case args.size
98
-
99
- when 0 then
100
- return nil
101
-
102
- when 1 then
103
- val = args[0]
104
-
105
- # Trivial parse... :-)
106
- return val if val.is_a?(Color)
107
-
108
- # Single value, assume grayscale
109
- return Color.new(val, val, val) if val.is_a?(Numeric)
110
-
111
- # Assume string
112
- str = val.to_s.upcase
113
- str = str[/[0-9A-F]{3,8}/] || ''
114
- case str.size
115
- when 3, 4 then
116
- r, g, b, a = str.scan(/[0-9A-F]/)
117
- when 6,8 then
118
- r, g, b, a = str.scan(/[0-9A-F]{2}/)
119
- else
120
- return nil
121
- end
122
-
123
- return Color.new(r,g,b,a || 255)
124
-
125
- when 3,4 then
126
- return Color.new(*args)
127
-
128
- end
129
- nil
130
- end
131
-
132
- def inspect
133
- to_s(true)
134
- end
135
-
136
- def to_s(add_hash = true)
137
- trans? ? to_rgba(add_hash) : to_rgb(add_hash)
138
- end
139
-
140
- def to_rgb(add_hash = true)
141
- (add_hash ? '#' : '') + to_hex(r) + to_hex(g) + to_hex(b)
142
- end
143
-
144
- def to_rgba(add_hash = true)
145
- to_rgb(add_hash) + to_hex(a)
146
- end
147
-
148
- def opaque?
149
- @a == 255
150
- end
151
-
152
- def trans?
153
- @a != 255
154
- end
155
-
156
- def grayscale?
157
- @r == @g && @g == @b
158
- end
159
-
160
- # Lighten color towards white. 0.0 is a no-op, 1.0 will return #FFFFFF
161
- def lighten(amt = BRIGHTNESS_DEFAULT)
162
- return self if amt <= 0
163
- return WHITE if amt >= 1.0
164
- val = Color.new(self)
165
- val.r += ((255-val.r) * amt).to_i
166
- val.g += ((255-val.g) * amt).to_i
167
- val.b += ((255-val.b) * amt).to_i
168
- val
169
- end
170
-
171
- # In place version of #lighten
172
- def lighten!(amt = BRIGHTNESS_DEFAULT)
173
- set(lighten(amt))
174
- self
175
- end
176
-
177
- # Darken a color towards full black. 0.0 is a no-op, 1.0 will return #000000
178
- def darken(amt = BRIGHTNESS_DEFAULT)
179
- return self if amt <= 0
180
- return BLACK if amt >= 1.0
181
- val = Color.new(self)
182
- val.r -= (val.r * amt).to_i
183
- val.g -= (val.g * amt).to_i
184
- val.b -= (val.b * amt).to_i
185
- val
186
- end
187
-
188
- # In place version of #darken
189
- def darken!(amt = BRIGHTNESS_DEFAULT)
190
- set(darken(amt))
191
- self
192
- end
193
-
194
- # Convert to grayscale, using perception-based weighting
195
- def grayscale
196
- val = Color.new(self)
197
- val.r = val.g = val.b = (0.2126 * val.r + 0.7152 * val.g + 0.0722 * val.b)
198
- val
199
- end
200
-
201
- # In place version of #grayscale
202
- def grayscale!
203
- set(grayscale)
204
- self
205
- end
206
-
207
- # Blend to a color amt % towards another color value, eg
208
- # red.blend(blue, 0.5) will be purple, white.blend(black, 0.5) will be gray, etc.
209
- def blend(other, amt)
210
- other = Color.parse(other)
211
- return Color.new(self) if amt <= 0 || other.nil?
212
- return Color.new(other) if amt >= 1.0
213
- val = Color.new(self)
214
- val.r += ((other.r - val.r)*amt).to_i
215
- val.g += ((other.g - val.g)*amt).to_i
216
- val.b += ((other.b - val.b)*amt).to_i
217
- val
218
- end
219
-
220
- # In place version of #blend
221
- def blend!(other, amt)
222
- set(blend(other, amt))
223
- self
224
- end
225
-
226
- # Class-level version for explicit blends of two values, useful with constants
227
- def self.blend(col1, col2, amt)
228
- col1 = Color.parse(col1)
229
- col2 = Color.parse(col2)
230
- col1.blend(col2, amt)
231
- end
232
-
233
- protected
234
-
235
- # Convert int to string hex, eg 255 => 'FF'
236
- def to_hex(val)
237
- HEXVAL[val / 16] + HEXVAL[val % 16]
238
- end
239
-
240
- # Convert int or string to int, eg 80 => 80, 'FF' => 255, '7' => 119
241
- def from_hex(val)
242
- if val.is_a?(String)
243
- # Double up if single char form
244
- val = val + val if val.size == 1
245
- # Convert to integer
246
- val = val.hex
247
- end
248
- # Clamp
249
- val = 0 if val < 0
250
- val = 255 if val > 255
251
- val
252
- end
253
-
254
- public
255
-
256
- # Some constants for general use
257
- WHITE = Color.new(255,255,255).freeze
258
- BLACK = Color.new(0,0,0).freeze
259
-
260
- end
261
-
262
- # "Global" method for creating Color objects, eg:
263
- # new_color = rgb(params[:new_color])
264
- # style="border: 1px solid <%= rgb(10,50,80).lighten %>"
265
- def rgb(*args)
266
- Color.parse(*args)
267
- end
268
-
269
-
@@ -1,69 +0,0 @@
1
- require 'digest/md5'
2
- module Log
3
- def self.fingerprint(obj)
4
- return obj.fingerprint if obj.respond_to?(:fingerprint)
5
-
6
- case obj
7
- when nil
8
- "nil"
9
- when TrueClass
10
- "true"
11
- when FalseClass
12
- "false"
13
- when Symbol
14
- ":" << obj.to_s
15
- when String
16
- if obj.length > 100
17
- digest = Digest::MD5.hexdigest(obj)
18
- "'" << obj.slice(0,30) << "<...#{obj.length} - #{digest[0..4]}...>" << obj.slice(-10,30)<< "'"
19
- else
20
- "'" << obj << "'"
21
- end
22
- when ConcurrentStream
23
- name = obj.inspect + " " + obj.object_id.to_s
24
- name += " #{obj.filename}" if obj.filename
25
- name
26
- when IO
27
- (obj.respond_to?(:filename) and obj.filename ) ? "<IO:" + (obj.filename || obj.inspect + rand(100000)) + ">" : obj.inspect + " " + obj.object_id.to_s
28
- when File
29
- "<File:" + obj.path + ">"
30
- when Array
31
- if (length = obj.length) > 10
32
- "[#{length}--" << (obj.values_at(0,1, length / 2, -2, -1).collect{|e| fingerprint(e)} * ",") << "]"
33
- else
34
- "[" << (obj.collect{|e| fingerprint(e) } * ", ") << "]"
35
- end
36
- when Hash
37
- if obj.length > 10
38
- "H:{"<< fingerprint(obj.keys) << ";" << fingerprint(obj.values) << "}"
39
- else
40
- new = "{"
41
- obj.each do |k,v|
42
- new << fingerprint(k) << '=>' << fingerprint(v) << ' '
43
- end
44
- if new.length > 1
45
- new[-1] = "}"
46
- else
47
- new << '}'
48
- end
49
- new
50
- end
51
- when Float
52
- if obj.abs > 10
53
- "%.1f" % obj
54
- elsif obj.abs > 1
55
- "%.3f" % obj
56
- else
57
- "%.6f" % obj
58
- end
59
- when Thread
60
- if obj["name"]
61
- obj["name"]
62
- else
63
- obj.inspect
64
- end
65
- else
66
- obj.to_s
67
- end
68
- end
69
- end