tattletail 0.0.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.
- data/.gitignore +4 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/README +0 -0
- data/Rakefile +1 -0
- data/lib/tattletail/version.rb +3 -0
- data/lib/tattletail.rb +270 -0
- data/tattletail.gemspec +25 -0
- metadata +89 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use 1.9.2@tattletail --create
|
data/Gemfile
ADDED
data/README
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/tattletail.rb
ADDED
@@ -0,0 +1,270 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'benchmark'
|
3
|
+
require 'colorful'
|
4
|
+
require 'tattletail/version'
|
5
|
+
|
6
|
+
module Tattletail
|
7
|
+
COLORS = { :count => '00a0b0',
|
8
|
+
:file => '444',
|
9
|
+
:context => '999',
|
10
|
+
:self => '793A57',
|
11
|
+
:method => 'fff',
|
12
|
+
:args => 'EB6841',
|
13
|
+
:result => '2DE04D',
|
14
|
+
:result_yaml => '105023',
|
15
|
+
:time_good => 'EDC951',
|
16
|
+
:time_bad => 'CC333F' }
|
17
|
+
|
18
|
+
def self.reset
|
19
|
+
$_tma_count = 0
|
20
|
+
$_tma_indent = 0
|
21
|
+
$_tma_last_indent = 0
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.inc
|
25
|
+
$_tma_count += 1
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.indent
|
29
|
+
$_tma_indent += 1
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.outdent
|
33
|
+
$_tma_indent -= 1
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.remember_indent
|
37
|
+
$_tma_last_indent = $_tma_indent
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.count
|
41
|
+
$_tma_count ||= 0
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.indent_level
|
45
|
+
$_tma_indent ||= 0
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.indent_changed?
|
49
|
+
$_tma_indent < $_tma_last_indent
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.count_str
|
53
|
+
" ##{count.to_s} ".color(COLORS[:count]).bold
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.self_str passed_self
|
57
|
+
passed_self.to_s.color(COLORS[:self])
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.file_str method_caller
|
61
|
+
file_name, line_number = method_caller[0].split(':', 3)
|
62
|
+
"#{file_name}:#{line_number}".color(COLORS[:file])
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.context_str method_caller
|
66
|
+
file_name, line_number, context = method_caller[0].split(':', 3)
|
67
|
+
begin
|
68
|
+
actual_line = File.readlines(file_name)[line_number.to_i - 1].strip
|
69
|
+
rescue Exception => e
|
70
|
+
actual_line = "Unable to open #{file_name}:#{line_number}"
|
71
|
+
end
|
72
|
+
"#{context} ... #{actual_line}".color(COLORS[:context])
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.method_str method_name, *args
|
76
|
+
name_str = "#{method_name}".bold
|
77
|
+
args_str = "(#{args.map {|a| a.inspect.size > 150 ? a.to_s : a.inspect}.map {|a| a.color(COLORS[:args])}.join(', ')})"
|
78
|
+
name_str + args_str
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.indent_str
|
82
|
+
indent_level.times.inject('') {|m| m += " │ "}
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.start_indent_str
|
86
|
+
indent_str.reverse.sub(" │", "─├").reverse + "─┬─"
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.cont_indent_str
|
90
|
+
"#{indent_str} │ "
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.end_indent_str
|
94
|
+
"#{indent_str} └─"
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.time_str seconds
|
98
|
+
time_str = (' ' * count.to_s.size) + ("%.4f sec" % seconds)
|
99
|
+
seconds > 0.05 ? time_str.color(COLORS[:time_bad]) : time_str.color(COLORS[:time_good])
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.result_str result, indent_str
|
103
|
+
result.to_s.color(COLORS[:result]) + if result.instance_variables.any? && ENV['SHOW_YAML']
|
104
|
+
"\n" + indent_str + " " + result.to_yaml.each_line.map do |l|
|
105
|
+
l.gsub(/\n/,'').color(COLORS[:result_yaml])
|
106
|
+
end.join("\n").gsub(/\n/, "\n#{indent_str} ")
|
107
|
+
else
|
108
|
+
''
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def tattle_on(*method_names)
|
113
|
+
method_names.each do |method_name|
|
114
|
+
if class_method? method_name
|
115
|
+
tattle_on_class_method method_name
|
116
|
+
else
|
117
|
+
tattle_on_instance_method method_name
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def tattle_on_class_method(*method_names)
|
123
|
+
method_names.each do |method_name|
|
124
|
+
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
125
|
+
class << self
|
126
|
+
#{make_talk method_name}
|
127
|
+
end
|
128
|
+
EOS
|
129
|
+
end
|
130
|
+
end
|
131
|
+
alias tattle_on_class_methods tattle_on_class_method
|
132
|
+
|
133
|
+
def tattle_on_instance_method(*method_names)
|
134
|
+
method_names.each do |method_name|
|
135
|
+
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
136
|
+
#{make_talk method_name}
|
137
|
+
EOS
|
138
|
+
end
|
139
|
+
end
|
140
|
+
alias tattle_on_instance_methods tattle_on_instance_method
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
def class_method? method_name
|
145
|
+
class_eval { respond_to? method_name }
|
146
|
+
end
|
147
|
+
|
148
|
+
def make_talk method_name
|
149
|
+
original_method = "_quiet_#{method_name}"
|
150
|
+
<<-EOF
|
151
|
+
if method_defined?(:#{original_method})
|
152
|
+
return
|
153
|
+
end
|
154
|
+
alias #{original_method} #{method_name}
|
155
|
+
|
156
|
+
def #{method_name}(*args, &blk)
|
157
|
+
Tattletail.inc
|
158
|
+
|
159
|
+
count_str = Tattletail.count_str
|
160
|
+
|
161
|
+
indent_str = Tattletail.indent_str
|
162
|
+
start_indent_str = Tattletail.start_indent_str
|
163
|
+
cont_indent_str = Tattletail.cont_indent_str
|
164
|
+
end_indent_str = Tattletail.end_indent_str
|
165
|
+
|
166
|
+
method_str = Tattletail.method_str :#{method_name}, *args
|
167
|
+
file_str = Tattletail.file_str(caller)
|
168
|
+
context_str = Tattletail.context_str(caller)
|
169
|
+
self_str = Tattletail.self_str(self)
|
170
|
+
|
171
|
+
if defined?(Rails)
|
172
|
+
file_str.sub!(Rails.root.to_s, '')
|
173
|
+
end
|
174
|
+
|
175
|
+
puts indent_str
|
176
|
+
puts start_indent_str + count_str + self_str + "." + method_str + " called"
|
177
|
+
puts "\#{cont_indent_str} \#{file_str}"
|
178
|
+
puts "\#{cont_indent_str} \#{context_str}"
|
179
|
+
|
180
|
+
Tattletail.indent
|
181
|
+
result = nil
|
182
|
+
seconds = Benchmark.realtime { result = #{original_method}(*args, &blk) }
|
183
|
+
time_str = Tattletail.time_str(seconds)
|
184
|
+
result_str = Tattletail.result_str(result, indent_str)
|
185
|
+
Tattletail.outdent
|
186
|
+
|
187
|
+
puts cont_indent_str if Tattletail.indent_changed?
|
188
|
+
puts end_indent_str + count_str + self_str + "." + method_str + " ⊢ " + result_str
|
189
|
+
|
190
|
+
Tattletail.remember_indent
|
191
|
+
|
192
|
+
puts indent_str + " " + time_str
|
193
|
+
|
194
|
+
result
|
195
|
+
end
|
196
|
+
EOF
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
Tattletail.reset
|
202
|
+
|
203
|
+
class Object
|
204
|
+
extend Tattletail
|
205
|
+
end
|
206
|
+
|
207
|
+
class Fib
|
208
|
+
def no_args
|
209
|
+
5
|
210
|
+
end
|
211
|
+
tattle_on :no_args
|
212
|
+
|
213
|
+
def fib x
|
214
|
+
return 1 if x <= 2
|
215
|
+
fib(x - 1) + fib(x - 2)
|
216
|
+
end
|
217
|
+
tattle_on_instance_method :fib
|
218
|
+
|
219
|
+
def self.fib x
|
220
|
+
return 1 if x <= 2
|
221
|
+
fib(x - 1) + fib(x - 2)
|
222
|
+
end
|
223
|
+
tattle_on :fib
|
224
|
+
|
225
|
+
def self.find x
|
226
|
+
return 1 if x <= 2
|
227
|
+
find(x - 1) + find(x - 2)
|
228
|
+
end
|
229
|
+
tattle_on :find
|
230
|
+
|
231
|
+
def find x
|
232
|
+
x * 2
|
233
|
+
end
|
234
|
+
tattle_on_instance_method :find
|
235
|
+
|
236
|
+
def fib_block &blk
|
237
|
+
fib yield
|
238
|
+
end
|
239
|
+
tattle_on :fib_block
|
240
|
+
end
|
241
|
+
|
242
|
+
module Merge
|
243
|
+
extend Tattletail
|
244
|
+
|
245
|
+
def self.sample_array
|
246
|
+
[3,7,5,1,2,9,8,0,2,3,5,2,4,1,6,7,8,4,6,2,1]
|
247
|
+
end
|
248
|
+
|
249
|
+
def self.mergesort(list = sample_array)
|
250
|
+
return list if list.size <= 1
|
251
|
+
mid = list.size / 2
|
252
|
+
left = list[0, mid]
|
253
|
+
right = list[mid, list.size]
|
254
|
+
merge(mergesort(left), mergesort(right))
|
255
|
+
end
|
256
|
+
tattle_on :mergesort
|
257
|
+
|
258
|
+
def self.merge(left, right)
|
259
|
+
sorted = []
|
260
|
+
until left.empty? or right.empty?
|
261
|
+
if left.first <= right.first
|
262
|
+
sorted << left.shift
|
263
|
+
else
|
264
|
+
sorted << right.shift
|
265
|
+
end
|
266
|
+
end
|
267
|
+
sorted.concat(left).concat(right)
|
268
|
+
end
|
269
|
+
tattle_on :merge
|
270
|
+
end
|
data/tattletail.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "tattletail/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "tattletail"
|
7
|
+
s.version = Tattletail::VERSION
|
8
|
+
s.authors = ["Nick Karpenske"]
|
9
|
+
s.email = ["randland@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Ruby method call observer}
|
12
|
+
s.description = %q{Provides a method to watch specific methods and print them when they are called}
|
13
|
+
|
14
|
+
s.rubyforge_project = "tattletail"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
s.add_development_dependency "fuubar"
|
24
|
+
s.add_runtime_dependency "colorful"
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tattletail
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nick Karpenske
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-08-29 00:00:00.000000000 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
requirement: &2157100980 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *2157100980
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: fuubar
|
28
|
+
requirement: &2157100560 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *2157100560
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: colorful
|
39
|
+
requirement: &2157100140 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *2157100140
|
48
|
+
description: Provides a method to watch specific methods and print them when they
|
49
|
+
are called
|
50
|
+
email:
|
51
|
+
- randland@gmail.com
|
52
|
+
executables: []
|
53
|
+
extensions: []
|
54
|
+
extra_rdoc_files: []
|
55
|
+
files:
|
56
|
+
- .gitignore
|
57
|
+
- .rvmrc
|
58
|
+
- Gemfile
|
59
|
+
- README
|
60
|
+
- Rakefile
|
61
|
+
- lib/tattletail.rb
|
62
|
+
- lib/tattletail/version.rb
|
63
|
+
- tattletail.gemspec
|
64
|
+
has_rdoc: true
|
65
|
+
homepage: ''
|
66
|
+
licenses: []
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project: tattletail
|
85
|
+
rubygems_version: 1.6.2
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: Ruby method call observer
|
89
|
+
test_files: []
|