putter 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/README.md +21 -21
- data/lib/putter/follower.rb +2 -2
- data/lib/putter/method_creator.rb +16 -6
- data/lib/putter/print_strategy.rb +4 -4
- data/lib/putter/proxy_method_data.rb +7 -4
- data/lib/putter/version.rb +1 -1
- data/lib/putter/watcher.rb +17 -30
- data/lib/putter/watcher_data.rb +38 -0
- data/lib/putter.rb +1 -0
- data/putter.gemspec +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16b81ce160fb22785ce8b1bdce7822783ba85eec
|
4
|
+
data.tar.gz: 7bc3095434de6035e590c28a37c8d435216a5e20
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8334e5bea55fae12d4e65fd35d1077069c32895f71fe26c06673b9f006a36e6693de536753d0b13f8158e89a5a4a76d3ec8c486d055389b29ac5c778fb5b373c
|
7
|
+
data.tar.gz: 30885b70b4ae1d78a1b74a2eaae951c91175e1879abd95e4721ed2c5dffdecc51c83f7b187108c2273ed538ea18f9a2abd728593e6e2f21bbccaa1630d4f184a
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,10 @@
|
|
1
1
|
# CHANGELOG
|
2
|
+
### 0.4.0 - 2016-08-16
|
3
|
+
- Add methods option to `Putter.watch`
|
4
|
+
- Refactor watch method to use registry
|
5
|
+
- Refactor method creation specs
|
6
|
+
- Update README
|
7
|
+
|
2
8
|
### 0.3.0 - 2016-07-08
|
3
9
|
- Add `Putter.watch` ability to watch a class and instances created by that class
|
4
10
|
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -2,9 +2,7 @@
|
|
2
2
|
|
3
3
|
It rhymes with gooder, not gutter.
|
4
4
|
|
5
|
-
Putter is a tool for more easily implementing puts debugging. Instead of littering files with various puts statements, you can wrap an object with a follower and print out anytime a method is called on that object. This will follow the object throughout its path in the stack.
|
6
|
-
|
7
|
-
For now Putter can only follow a specific the speficic object that it wraps. It currently does not watch a class to see what objects were passed to it unless that specific instance of the class is passed through the stack.
|
5
|
+
Putter is a tool for more easily implementing puts debugging. Instead of littering files with various puts statements, you can wrap an object with a follower or watcher and print out anytime a method is called on that object. This will follow the object throughout its path in the stack.
|
8
6
|
|
9
7
|
## Installation
|
10
8
|
|
@@ -26,11 +24,11 @@ Or install it yourself as:
|
|
26
24
|
|
27
25
|
There are two ways to use putter. `Putter.follow` and `Putter.watch`.
|
28
26
|
|
29
|
-
### Putter.follow
|
27
|
+
### `Putter.follow`
|
30
28
|
|
31
|
-
`Putter.follow` will allow you to create a wrapper around an object and then you can pass that wrapped object around. The advantage to using follow is that if a method is called that doesn't exist, or a method is created at runtime, the wrapped object will intercept those calls. This works on both instances and classes.
|
29
|
+
`Putter.follow` will allow you to create a wrapper around an object and then you can pass that wrapped object around. The advantage to using `follow` is that if a method is called that doesn't exist, or a method is created at runtime, the wrapped object will intercept those calls. This works on both instances and classes.
|
32
30
|
|
33
|
-
Additionally, following an object will not allow you to intercept calls to a class that occurred outside the wrapped object. For that functionality, use `Putter.watch
|
31
|
+
However, following a class will not result in created instances of that class being followed. Additionally, following an object will not allow you to intercept calls to a class that occurred outside the wrapped object. For that functionality, use `Putter.watch`.
|
34
32
|
|
35
33
|
`Putter.follow` usage:
|
36
34
|
|
@@ -62,16 +60,16 @@ Putter Debugging: Object instance ./putter/README.md:57 -- Method: :hello, Args:
|
|
62
60
|
```ruby
|
63
61
|
Putter.follow(
|
64
62
|
object_to_follow,
|
65
|
-
label: "My object", # Label to use after "Putter Debugging: My object". Will be "ClassName" for classes or "ClassName instance" for instances
|
66
|
-
methods: ["
|
63
|
+
label: "My object", # Optional - Label to use after "Putter Debugging: My object". Will be "ClassName" for classes or "ClassName instance" for instances
|
64
|
+
methods: ["my_method"], # Optional - If array is empty, then all methods will be watched. Otherwise, this is an array of methods to print debugging input for
|
67
65
|
)
|
68
66
|
```
|
69
67
|
|
70
|
-
### Putter.watch
|
68
|
+
### `Putter.watch`
|
71
69
|
|
72
|
-
`Putter.watch` can be used on classes to follow created instances of the class or to intercept method calls that occur throughout your application.
|
70
|
+
`Putter.watch` can be used on classes to follow created instances of the class or to intercept class method calls that occur throughout your application.
|
73
71
|
|
74
|
-
`Putter.
|
72
|
+
`Putter.watch` usage:
|
75
73
|
|
76
74
|
```ruby
|
77
75
|
class MyObject
|
@@ -93,16 +91,18 @@ my_obj.hello_instance("world", "!")
|
|
93
91
|
Will output:
|
94
92
|
|
95
93
|
```bash
|
96
|
-
Putter Debugging:
|
97
|
-
Putter Debugging:
|
94
|
+
Putter Debugging: MyObject ./putter/README.md:96 -- Method: :hello_class, Args: ["world", "!"], Result: The class says hello world!
|
95
|
+
Putter Debugging: MyObject ./putter/README.md:96 -- Method: :new, Args: [], Result: #<MyObject:0x0000000000>
|
96
|
+
Putter Debugging: MyObject instance 1 ./putter/README.md:97 -- Method: :hello_instance, Args: ["world", "!"], Result: The instance says hello world!
|
98
97
|
```
|
99
98
|
|
100
|
-
#### `Putter.
|
99
|
+
#### `Putter.watch` Options
|
101
100
|
|
102
101
|
```ruby
|
103
102
|
Putter.watch(
|
104
|
-
|
105
|
-
label: "My
|
103
|
+
ClassToWatch,
|
104
|
+
label: "My class", # Optional - Label to use after "Putter Debugging: My class". Will be "ClassName" for classes or "ClassName instance #" for instances
|
105
|
+
methods: ["my_method"], # Optional - If array is empty, then all methods will be watched. Otherwise, this is an array of methods to print debugging input for
|
106
106
|
)
|
107
107
|
```
|
108
108
|
|
@@ -112,13 +112,13 @@ Putter currently has 3 configuration options:
|
|
112
112
|
|
113
113
|
```ruby
|
114
114
|
Putter.configure do |config|
|
115
|
-
# 'print_strategy' takes a block that receives
|
116
|
-
# method, args
|
115
|
+
# 'print_strategy' takes a block that receives a data object with the label, line,
|
116
|
+
# method, args string, and result respectively. This block will be used after each method
|
117
117
|
# is called, it must contain puts or logger calls, to print or any other method callbacks
|
118
118
|
# that are helpful.
|
119
119
|
# Defaults to Putter::PrintStrategy::Default
|
120
|
-
config.print_strategy = Proc.new do |
|
121
|
-
puts "#{line} - Label: #{label}, Method: #{method}, Args: #{args}, Result: #{result}"
|
120
|
+
config.print_strategy = Proc.new do |data|
|
121
|
+
puts "#{data.line} - Label: #{data.label}, Method: #{data.method}, Args: #{data.args}, Result: #{data.result}"
|
122
122
|
end
|
123
123
|
|
124
124
|
# 'ignore_methods_from' takes an array of class names and will ignore both class and instance methods
|
@@ -128,7 +128,7 @@ Putter.configure do |config|
|
|
128
128
|
|
129
129
|
# 'methods_whitelist' takes an array of methods and will always proxy and debug those methods
|
130
130
|
# regardless of whether or not the class is ignored and regardless of what methods are passed
|
131
|
-
# in when running 'Putter.follow'
|
131
|
+
# in when running 'Putter.follow' or 'Putter.watch'
|
132
132
|
config.methods_whitelist = [:to_s]
|
133
133
|
end
|
134
134
|
```
|
data/lib/putter/follower.rb
CHANGED
@@ -28,9 +28,9 @@ module Putter
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def add_method(method)
|
31
|
-
data = ProxyMethodData.new(
|
31
|
+
data = ProxyMethodData.new({ label: @label, method: method})
|
32
32
|
|
33
|
-
|
33
|
+
add_putter_instance_method_to_proxy(@proxy, data)
|
34
34
|
end
|
35
35
|
|
36
36
|
def _add_method?(method)
|
@@ -1,14 +1,24 @@
|
|
1
1
|
module Putter
|
2
2
|
module MethodCreator
|
3
|
-
def
|
3
|
+
def add_putter_instance_method_to_proxy(proxy, data)
|
4
|
+
add_putter_method_to_proxy(proxy, data, :instance_exec)
|
5
|
+
end
|
6
|
+
|
7
|
+
def add_putter_class_method_to_proxy(proxy, data)
|
8
|
+
add_putter_method_to_proxy(proxy, data, :module_exec)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def add_putter_method_to_proxy(proxy, data, eval_method)
|
4
14
|
proxy.send(eval_method, data) do |data|
|
5
15
|
define_method(data.method) do |*proxy_args, &blk|
|
6
16
|
line = caller.find {|call| call.match(data.stack_trace_ignore_regex)}
|
7
|
-
line = line.split(::Dir.pwd)[1]
|
8
|
-
|
9
|
-
result = super *proxy_args, &blk
|
10
|
-
::Putter.configuration.print_strategy.call data
|
11
|
-
result
|
17
|
+
data.line = line.split(::Dir.pwd)[1]
|
18
|
+
data.args = proxy_args.to_s
|
19
|
+
data.result = super *proxy_args, &blk
|
20
|
+
::Putter.configuration.print_strategy.call data
|
21
|
+
data.result
|
12
22
|
end
|
13
23
|
end
|
14
24
|
end
|
@@ -2,10 +2,10 @@ require "colorize"
|
|
2
2
|
|
3
3
|
module Putter
|
4
4
|
module PrintStrategy
|
5
|
-
Default = Proc.new do |
|
6
|
-
prefix = "\tPutter Debugging: #{label} ".colorize(:cyan)
|
7
|
-
line = !line.nil? ? ".#{line} " : " "
|
8
|
-
suffix = "-- Method: :#{method}, Args: #{args}, Result: #{result}".colorize(:green)
|
5
|
+
Default = Proc.new do |data|
|
6
|
+
prefix = "\tPutter Debugging: #{data.label} ".colorize(:cyan)
|
7
|
+
line = !data.line.nil? ? ".#{data.line} " : " "
|
8
|
+
suffix = "-- Method: :#{data.method}, Args: #{data.args}, Result: #{data.result}".colorize(:green)
|
9
9
|
puts prefix + line + suffix
|
10
10
|
end
|
11
11
|
end
|
@@ -2,11 +2,14 @@ module Putter
|
|
2
2
|
class ProxyMethodData
|
3
3
|
STACK_TRACE_IGNORE_REGEX = /(?!.*(\.rbenv|\.rvm|\/lib\/putter\/follower))(^.*$)/
|
4
4
|
|
5
|
-
|
5
|
+
attr_accessor :label, :line, :method, :args, :result
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@
|
9
|
-
@
|
7
|
+
def initialize(params)
|
8
|
+
@label = params[:label]
|
9
|
+
@line = params[:line]
|
10
|
+
@method = params[:method]
|
11
|
+
@args = params[:args]
|
12
|
+
@result = params[:result]
|
10
13
|
end
|
11
14
|
|
12
15
|
def stack_trace_ignore_regex
|
data/lib/putter/version.rb
CHANGED
data/lib/putter/watcher.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
module Putter
|
2
|
-
|
2
|
+
module Watcher
|
3
3
|
extend MethodCreator
|
4
4
|
|
5
|
-
@
|
5
|
+
@registry = {}
|
6
6
|
|
7
7
|
def self.watch(obj, options={})
|
8
|
-
|
8
|
+
data = WatcherData.new(options, obj)
|
9
|
+
@registry[obj.singleton_class] = data
|
9
10
|
|
10
11
|
class << obj
|
11
12
|
prepend InstanceFollower
|
@@ -13,41 +14,27 @@ module Putter
|
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
16
|
-
def self.
|
17
|
-
|
18
|
-
|
19
|
-
methods_to_proxy(klass).each do |method|
|
20
|
-
data = ProxyMethodData.new(method, label)
|
21
|
-
add_putter_method_to_proxy(proxy, :module_exec, data)
|
22
|
-
end
|
23
|
-
|
24
|
-
proxy
|
17
|
+
def self.registry
|
18
|
+
@registry
|
25
19
|
end
|
26
20
|
|
27
|
-
def self.
|
28
|
-
|
29
|
-
|
30
|
-
Putter.configuration.ignore_methods_from.each do |klass|
|
31
|
-
ignored_methods += klass.methods
|
32
|
-
end
|
33
|
-
|
34
|
-
klass.instance_methods - ignored_methods + Putter.configuration.methods_whitelist.map(&:to_sym) + [:new]
|
21
|
+
def self.label_for(klass)
|
22
|
+
@registry[klass].label
|
35
23
|
end
|
36
24
|
|
37
|
-
def self.
|
38
|
-
@
|
25
|
+
def self.methods_for(klass)
|
26
|
+
@registry[klass].proxy_methods
|
39
27
|
end
|
40
28
|
|
41
|
-
def self.
|
42
|
-
|
43
|
-
end
|
29
|
+
def self.class_proxy(klass)
|
30
|
+
proxy = MethodProxy.new
|
44
31
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
else
|
49
|
-
@label = class_name
|
32
|
+
Putter::Watcher.methods_for(klass).each do |method|
|
33
|
+
data = ProxyMethodData.new({ label: Putter::Watcher.label_for(klass), method: method })
|
34
|
+
add_putter_class_method_to_proxy(proxy, data)
|
50
35
|
end
|
36
|
+
|
37
|
+
proxy
|
51
38
|
end
|
52
39
|
end
|
53
40
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Putter
|
2
|
+
class WatcherData
|
3
|
+
attr_accessor :label, :proxy_methods
|
4
|
+
|
5
|
+
def initialize(options, klass)
|
6
|
+
_set_label(options[:label], klass)
|
7
|
+
_set_methods(options[:methods], klass)
|
8
|
+
end
|
9
|
+
|
10
|
+
def _set_label(label, klass)
|
11
|
+
if !label.nil? && label != ""
|
12
|
+
@label = label
|
13
|
+
else
|
14
|
+
@label = klass.name
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def _set_methods(methods, klass)
|
19
|
+
if methods.nil?
|
20
|
+
@proxy_methods = _methods_to_proxy(klass.singleton_class)
|
21
|
+
elsif !methods.is_a?(Array)
|
22
|
+
@proxy_methods = [methods]
|
23
|
+
else
|
24
|
+
@proxy_methods = methods
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def _methods_to_proxy(singleton_klass)
|
29
|
+
ignored_methods = []
|
30
|
+
|
31
|
+
Putter.configuration.ignore_methods_from.each do |klass|
|
32
|
+
ignored_methods += klass.methods
|
33
|
+
end
|
34
|
+
|
35
|
+
singleton_klass.instance_methods - ignored_methods + Putter.configuration.methods_whitelist.map(&:to_sym) + [:new]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/putter.rb
CHANGED
data/putter.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "putter"
|
8
8
|
spec.version = Putter::VERSION
|
9
9
|
spec.authors = ["John DeWyze"]
|
10
|
-
spec.email = ["
|
10
|
+
spec.email = ["putter@dewyze.io"]
|
11
11
|
|
12
12
|
spec.description = "Putter provides a variety of methods to easily use puts debugging. It can reveal what methods are called, the arguments that were passed in, and what the result of the method call."
|
13
13
|
spec.summary = "Putter makes puts debugging easy."
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: putter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John DeWyze
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -84,7 +84,7 @@ description: Putter provides a variety of methods to easily use puts debugging.
|
|
84
84
|
can reveal what methods are called, the arguments that were passed in, and what
|
85
85
|
the result of the method call.
|
86
86
|
email:
|
87
|
-
-
|
87
|
+
- putter@dewyze.io
|
88
88
|
executables:
|
89
89
|
- console
|
90
90
|
- setup
|
@@ -116,6 +116,7 @@ files:
|
|
116
116
|
- lib/putter/proxy_method_data.rb
|
117
117
|
- lib/putter/version.rb
|
118
118
|
- lib/putter/watcher.rb
|
119
|
+
- lib/putter/watcher_data.rb
|
119
120
|
- putter.gemspec
|
120
121
|
homepage: https://github.com/dewyze/putter
|
121
122
|
licenses:
|