putter 0.3.0 → 0.4.0
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.
- 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:
|