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 ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.2@tattletail --create
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in tattletail.gemspec
4
+ gemspec
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,3 @@
1
+ module Tattletail
2
+ VERSION = "0.0.1"
3
+ end
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
@@ -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: []