pretty_debug 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/pretty_debug.rb +42 -183
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04efe0cf9dba9901b76596d083e6e2d7bcaedefe
|
4
|
+
data.tar.gz: 161511fa41ee80e11bbcf24d2b04449a972ad0c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49766af15d06ede86a35499730605b8dd5c618c62a2f44cf3657950a96c6a6eaf44bda77f52bd2fe3dbdd20b66a2a141d301c3a6adbe69cc0d2bc779be2dfedf
|
7
|
+
data.tar.gz: a2e8df34f7e48cb2bafe0ac02c6d1f9e1c73c4823a37a4cd4a5f0d131e58a7e63b5c1425c0442a3a01b46baf5d47da7f75773ed571c27362a54b2a54a4067c47
|
data/lib/pretty_debug.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
#!ruby
|
2
2
|
require "string"
|
3
|
-
require "ruby-prof"
|
4
3
|
require "utility"
|
5
4
|
|
6
5
|
module Kernel
|
@@ -16,132 +15,42 @@ module Kernel
|
|
16
15
|
end
|
17
16
|
end
|
18
17
|
|
19
|
-
class ValidationError < Exception; end
|
20
|
-
|
21
|
-
class Object
|
22
|
-
def expect s; raise ArgumentError.new("Expecting `#{s.inspect}`: #{inspect}") end
|
23
|
-
def case? *kases; kases.any?{|kase| kase === self} end
|
24
|
-
end
|
25
|
-
|
26
|
-
class Module
|
27
|
-
def basename; to_s.split("::").last end
|
28
|
-
end
|
29
|
-
|
30
|
-
class Array
|
31
|
-
def compatible? other
|
32
|
-
other.case?(Array) and
|
33
|
-
other.length == length
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
class Hash
|
38
|
-
def compatible? other
|
39
|
-
other.case?(Hash) and
|
40
|
-
other.size == size and
|
41
|
-
other.keys.all?{|k| key?(k)}
|
42
|
-
end
|
43
|
-
def ltsv *args
|
44
|
-
if args.empty? then
|
45
|
-
map{|k, v| "#{k}:#{v.to_s.tr("\t", " ")}"} else
|
46
|
-
args.map{|k| "#{k}:#{self[k].to_s.tr("\t", " ")}"}
|
47
|
-
end.join("\t")
|
48
|
-
end
|
49
|
-
end
|
50
|
-
class String
|
51
|
-
def parse_ltsv; Hash[chomp.split("\t").map{|f| f.split(":", 2)}] end
|
52
|
-
end
|
53
|
-
|
54
18
|
class PrettyDebug
|
55
19
|
attr_accessor :backtrace, :message
|
56
20
|
def self.new_internal
|
57
21
|
new.tap do |error|
|
58
|
-
called_location = clean(
|
22
|
+
called_location = clean(caller_locations)[2]
|
59
23
|
error.backtrace = clean($@).take_while{|a| a != called_location}
|
60
24
|
error.message = $!.message
|
61
25
|
end
|
62
26
|
end
|
63
|
-
Stackline = /\A(?'f'.+?):(?'l'\d+)(?::in `(?'m'.*)'|(?'m'.*))?\z/m
|
64
|
-
NoncallLine = /\Ablock(?: \(\d+ levels\))? in |\A\</
|
65
27
|
def self.message; $!.message.dup.tap{|s| s[0] = s[0].upcase}.sub(/(?<=[^.])\z/, ".") end
|
66
28
|
def self.clean stack
|
67
|
-
|
68
|
-
|
69
|
-
caller_file_i = $LOADED_FEATURES.index(caller.first.match(Stackline)[:f]).to_i
|
29
|
+
return [] if stack.to_a.empty?
|
30
|
+
caller_file_i = $LOADED_FEATURES.index(caller_location(0).path).to_i
|
70
31
|
stack
|
71
|
-
.map{|l|
|
32
|
+
.map{|l| [l.path.ellipsis(55), l.lineno, l.base_label]}
|
72
33
|
.transpose.tap do |_, _, m|
|
73
34
|
m.rotate!(-1)
|
74
35
|
m[0] = ""
|
75
36
|
while i = m.index{|m| m == "method_missing"}; m[i] = m[i - 1] end
|
76
37
|
end.transpose
|
77
|
-
.reject{|_, _, m| m =~ NoncallLine}
|
78
38
|
# .reject{|f, _, _| $LOADED_FEATURES.include?(f)}
|
79
39
|
# .reject{|f, _, _| $LOADED_FEATURES.index(f).to_i > caller_file_i}
|
80
40
|
end
|
81
41
|
end
|
82
42
|
|
83
|
-
#############################################
|
84
|
-
# Terminal formatting
|
85
|
-
#############################################
|
86
|
-
|
87
|
-
class String
|
88
|
-
def terminal_escape; "\"#{self}\"" end
|
89
|
-
def color sym; "#{vt100(30+
|
90
|
-
{black: 0, red: 1, green: 2, yellow: 3, blue: 4, magenta: 5, cyan: 6, white: 7}[sym]
|
91
|
-
)}#{self}#{vt100}" end
|
92
|
-
def bg sym; "#{vt100(40+
|
93
|
-
{black: 0, red: 1, green: 2, yellow: 3, blue: 4, magenta: 5, cyan: 6, white: 7}[sym]
|
94
|
-
)}#{self}#{vt100}" end
|
95
|
-
def bf; "#{vt100("01")}#{self}#{vt100}" end
|
96
|
-
|
97
|
-
private
|
98
|
-
def vt100 s = ""; "\e[#{s}m" end
|
99
|
-
end
|
100
|
-
|
101
|
-
class Object
|
102
|
-
def intercept &pr
|
103
|
-
tap{|x| puts "[Debug] #{caller[2][/.*?:\d+/]}:".color(:yellow); pr ? pr.call(x) : p(x)}
|
104
|
-
end
|
105
|
-
def forwardtrace sym
|
106
|
-
tap{puts "#{inspect}##{sym} defined at:", method(sym).source_location.join(":")}
|
107
|
-
end
|
108
|
-
def follow m; tap{puts "Next step: #{method(m).source_location
|
109
|
-
.chain{|a| a ? a.join(":") : "Unknown #{self}.#{m}"}
|
110
|
-
}"} end
|
111
|
-
def _?; tap{Test.testee.push(self)} end
|
112
|
-
end
|
113
|
-
|
114
|
-
=begin
|
115
|
-
class Module
|
116
|
-
def inspect
|
117
|
-
ans = ancestors.map{|m| "#{m.class.send(:to_s).downcase} #{m}"}.join(" < ")
|
118
|
-
var = (class_variables + instance_variables).join(", ")
|
119
|
-
var.empty? ? ans : "#{ans}#$/#{var}"
|
120
|
-
end
|
121
|
-
end
|
122
|
-
=end
|
123
|
-
|
124
43
|
class Proc
|
125
|
-
def source_location
|
126
|
-
|
44
|
+
def inspect; f, l = source_location; "Proc@#{File.basename(f)}:#{l}"
|
45
|
+
rescue; "Proc@source_unknown"
|
127
46
|
end
|
128
|
-
def inspect
|
129
|
-
f, l = source_location
|
130
|
-
"Proc@#{File.basename(f)}:#{l}"
|
131
|
-
rescue
|
132
|
-
"Proc@source_unknown"
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
class Method
|
137
|
-
def inspect; to_s end
|
138
|
-
def to_s; "#{receiver}.#{name}" end
|
139
47
|
end
|
48
|
+
class Method; def inspect; "#{receiver}.#{name}" end end
|
49
|
+
class UnboundMethod; def inspect; "#{owner}##{name}" end end
|
140
50
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
end
|
51
|
+
#############################################
|
52
|
+
# Terminal
|
53
|
+
#############################################
|
145
54
|
|
146
55
|
class Array
|
147
56
|
def inspect
|
@@ -149,25 +58,12 @@ class Array
|
|
149
58
|
.chain{|s| length < 2 ? "[#{s.join}]" : "[#$/#{s.join(",#$/").indent}#$/]"}
|
150
59
|
end
|
151
60
|
def align ellipsis_limit = nil
|
152
|
-
transpose
|
153
|
-
.map do |col|
|
61
|
+
transpose.map do |col|
|
154
62
|
just = case col.first; when Numeric then :rjust; else :ljust end
|
155
63
|
width = col.map{|cell| cell.to_s.length}.max
|
156
64
|
max = ellipsis_limit || width
|
157
65
|
col.map{|cell| cell.to_s.ellipsis(max).send(just, width.at_most(max))}
|
158
|
-
end
|
159
|
-
.transpose
|
160
|
-
=begin
|
161
|
-
col_widths = transpose.map{|col| col.map{|cell| cell.to_s.length}.max}
|
162
|
-
map{|row| [row, col_widths].transpose.map{|cell, l|
|
163
|
-
max = ellipsis_limit || l
|
164
|
-
l = l.at_most(max)
|
165
|
-
case cell
|
166
|
-
when Numeric then cell.to_s.ellipsis(max).rjust(l)
|
167
|
-
else cell.to_s.ellipsis(max).ljust(l)
|
168
|
-
end
|
169
|
-
}.join(sep)}
|
170
|
-
=end
|
66
|
+
end.transpose
|
171
67
|
end
|
172
68
|
end
|
173
69
|
|
@@ -182,79 +78,42 @@ class Hash
|
|
182
78
|
end
|
183
79
|
end
|
184
80
|
|
185
|
-
|
186
|
-
def
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
end
|
192
|
-
def self.testee_clear; @@testee = [] end
|
193
|
-
def self.testee_refer; @@testee end
|
194
|
-
def self.test title = "Test", &pr
|
195
|
-
testee_clear
|
196
|
-
t = Time.now
|
197
|
-
if pr.call == true
|
198
|
-
puts "#{title}. Succeeded (#{"%.2e" % t.till_now} secs)".color(:green)
|
199
|
-
else
|
200
|
-
puts "#{title}. Failed".color(:red),
|
201
|
-
*(testee_refer.map{|o| o.inspect.color(:red)} unless testee_refer.empty?)
|
81
|
+
class Object
|
82
|
+
def intercept &pr
|
83
|
+
tap do |x| puts \
|
84
|
+
"[Debug] #{caller_location(2).chain{|l| "#{l.basename}:#{l.lineno}"}}"
|
85
|
+
.color(:yellow),
|
86
|
+
x.inspect
|
202
87
|
end
|
203
|
-
rescue Exception
|
204
|
-
puts "#{title} ... Test Error".color(:red),
|
205
|
-
[$!.message, *PrettyDebug.clean($@).align.map{|row| row.join(":")}].map{|l| l.color(:red)}
|
206
88
|
end
|
207
89
|
end
|
208
90
|
|
209
|
-
|
210
|
-
def
|
211
|
-
def
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
end
|
91
|
+
class String
|
92
|
+
def terminal_escape; "\"#{self}\"" end
|
93
|
+
def color sym; "#{vt100(30+
|
94
|
+
{black: 0, red: 1, green: 2, yellow: 3, blue: 4, magenta: 5, cyan: 6, white: 7}[sym]
|
95
|
+
)}#{self}#{vt100}" end
|
96
|
+
def bg sym; "#{vt100(40+
|
97
|
+
{black: 0, red: 1, green: 2, yellow: 3, blue: 4, magenta: 5, cyan: 6, white: 7}[sym]
|
98
|
+
)}#{self}#{vt100}" end
|
99
|
+
def bf; "#{vt100("01")}#{self}#{vt100}" end
|
218
100
|
|
219
|
-
|
220
|
-
|
221
|
-
def benchmark i, &pr
|
222
|
-
Benchmark.prs = []
|
223
|
-
pr.call()
|
224
|
-
Benchmark.bm(i){|br| Benchmark.prs.each{|pr| br.report(""){pr.call()}}}
|
225
|
-
end
|
226
|
-
def alternative ≺ Benchmark.prs.push(pr) end
|
101
|
+
private
|
102
|
+
def vt100 s = ""; "\e[#{s}m" end
|
227
103
|
end
|
228
104
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
=begin
|
235
|
-
require "ruby-prof"
|
236
|
-
$prof_begin = false
|
237
|
-
def profile_on; $prof_begin = true; end
|
238
|
-
def profile switch = nil
|
239
|
-
yield if switch && $prof_begin.!
|
240
|
-
RubyProf.resume{$prof_result = yield}
|
241
|
-
open("/tmp/profile", "w"){|io|
|
242
|
-
# RubyProf::CallStackPrinter. # for kcachegring
|
243
|
-
RubyProf::GraphHtmlPrinter.
|
244
|
-
# RubyProf::GraphPrinter.
|
245
|
-
# RubyProf::AbstractPrinter.
|
246
|
-
new(RubyProf.stop).print(io)}
|
247
|
-
# IO.popen("kcachegrind /tmp/profile > #{File::NULL} 2>&1")
|
248
|
-
# IO.popen("firefox >#{File::NULL} /tmp/profile ")
|
249
|
-
IO.popen("google-chrome >#{File::NULL} /tmp/profile ")
|
250
|
-
$prof_result
|
251
|
-
end
|
105
|
+
#############################################
|
106
|
+
# LTSV
|
107
|
+
#############################################
|
252
108
|
|
253
|
-
|
254
|
-
def
|
255
|
-
|
256
|
-
|
257
|
-
|
109
|
+
class Hash
|
110
|
+
def ltsv *args
|
111
|
+
if args.empty? then
|
112
|
+
map{|k, v| "#{k}:#{v.to_s.tr("\t", " ")}"} else
|
113
|
+
args.map{|k| "#{k}:#{self[k].to_s.tr("\t", " ")}"}
|
114
|
+
end.join("\t")
|
258
115
|
end
|
259
116
|
end
|
260
|
-
|
117
|
+
class String
|
118
|
+
def parse_ltsv; Hash[chomp.split("\t").map{|f| f.split(":", 2)}] end
|
119
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pretty_debug
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sawa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: ''
|
14
14
|
email: []
|