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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7b61e558de7dab6687ddc1e44fcb1a66ae6a4669
4
- data.tar.gz: 23a571a29ea9c44223a86e9762d02d5eb13d7352
3
+ metadata.gz: 16b81ce160fb22785ce8b1bdce7822783ba85eec
4
+ data.tar.gz: 7bc3095434de6035e590c28a37c8d435216a5e20
5
5
  SHA512:
6
- metadata.gz: b700661ef9567e2e9f5b19880a491f0e37f7b7fd32597e024a04c0fd18df13bf5147add15a3dc49956a92850e0eb31df52eb13b1c89d0e31d03e00978f59b5d8
7
- data.tar.gz: a5c554a5f52c2181a8d39cedfbeb50950a4b3d5420c1f99cf453f08797edd4b44e25a8d307f36d1265c18d3aab53b9f30290460c2e4cd28df913bfead72d3915
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- putter (0.2.1)
4
+ putter (0.4.0)
5
5
  colorize (~> 0)
6
6
 
7
7
  GEM
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. However, following a class will not result in created instances of that class being followed.
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: ["value"], # If the value is nil, then all methods will be watched. Otherwise, this is an array of methods to print debugging input for
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.follow` usage:
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: Object ./putter/README.md:96 -- Method: :hello_class, Args: [:world, "!"], Result: "The class says hello world!"
97
- Putter Debugging: Object instance 1 ./putter/README.md:97 -- Method: :hello_instance, Args: [:world, "!"], Result: "The instance says hello world!"
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.follow` Options
99
+ #### `Putter.watch` Options
101
100
 
102
101
  ```ruby
103
102
  Putter.watch(
104
- ClassToFollow,
105
- label: "My object", # Label to use after "Putter Debugging: My object". Will be "ClassName" for classes or "ClassName instance #" for instances
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 five arguments with the label, line,
116
- # method, args array, and result respectively. This block will be used after each method
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 |label, line, method, args, result|
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
  ```
@@ -28,9 +28,9 @@ module Putter
28
28
  end
29
29
 
30
30
  def add_method(method)
31
- data = ProxyMethodData.new(method, @label)
31
+ data = ProxyMethodData.new({ label: @label, method: method})
32
32
 
33
- add_putter_method_to_proxy(@proxy, :instance_exec, data)
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 add_putter_method_to_proxy(proxy, eval_method, data)
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
- args_string = proxy_args.to_s
9
- result = super *proxy_args, &blk
10
- ::Putter.configuration.print_strategy.call data.label, line, data.method, args_string, result
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 |label, line, method, args, result|
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
- attr_reader :method, :label
5
+ attr_accessor :label, :line, :method, :args, :result
6
6
 
7
- def initialize(method, label)
8
- @method = method
9
- @label = label
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
@@ -1,3 +1,3 @@
1
1
  module Putter
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -1,11 +1,12 @@
1
1
  module Putter
2
- class Watcher
2
+ module Watcher
3
3
  extend MethodCreator
4
4
 
5
- @label = ""
5
+ @registry = {}
6
6
 
7
7
  def self.watch(obj, options={})
8
- _set_label(options[:label], obj.name)
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.class_proxy(klass)
17
- proxy = MethodProxy.new
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.methods_to_proxy(klass)
28
- ignored_methods = []
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.label
38
- @label
25
+ def self.methods_for(klass)
26
+ @registry[klass].proxy_methods
39
27
  end
40
28
 
41
- def self.label=(label)
42
- @label = label
43
- end
29
+ def self.class_proxy(klass)
30
+ proxy = MethodProxy.new
44
31
 
45
- def self._set_label(label, class_name)
46
- if !label.nil? && label != ""
47
- @label = label
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
@@ -6,6 +6,7 @@ require "putter/method_proxy"
6
6
  require "putter/print_strategy"
7
7
  require "putter/proxy_method_data"
8
8
  require "putter/version"
9
+ require "putter/watcher_data"
9
10
 
10
11
  require "putter/follower"
11
12
  require "putter/watcher"
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 = ["john.dewyze@gmail.com"]
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.3.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-07-08 00:00:00.000000000 Z
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
- - john.dewyze@gmail.com
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: