tapping_device 0.4.11 → 0.5.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d8328ddf34918bc8be607eb8bad74e3588f435a13dcefdf0690dd7f03ec4774f
4
- data.tar.gz: d34dd35817a235e92e12f7c086a3911d11c8564851a29e3ae31676b9b699f67f
3
+ metadata.gz: 231efa59a44f630df303db52d0d3bb460698c02a116374838e4bad4d71d7f69e
4
+ data.tar.gz: ca80df8a0ea00350c1e074628425848b5cba4d7f53a7aa4176947d55a3164929
5
5
  SHA512:
6
- metadata.gz: c12632e9ecdfed8970b36f191f2d2ea736cf1dc61a12096559cf25dfd791ee22c240e80d0230ffad4dc334d8dd9e6071efb1d6372256e339cd4387f79316a995
7
- data.tar.gz: 92a81f59e1f130ea25a41e58fb06c4ca153fa0eaa021094c59782737d16af34160ccb257a42a1bdd0a589d3e739a17ebf126c2cf72e233a0b61eab133825311e
6
+ metadata.gz: 77131aab9e85a2661694ee57470b9067ee44d479d574cbe395eefabd7f88350eaf31071c4ed0d117b1608856e9e6beff9d7ccae592a665c8969231425dafdc43
7
+ data.tar.gz: c06dedd14da7798cf93d80ae0d4866928c9e2522184f453588691fdf1a3220b21cfdf953f04575f1015cc1cb58c5bcb2cb5673fd9384cf5515855d048d0bbdb3
Binary file
@@ -33,10 +33,17 @@ jobs:
33
33
  gem install bundler
34
34
  bundle install --jobs 4 --retry 3
35
35
 
36
- - name: Run test with Rails ${{ matrix.rails_version }} and publish result
37
- uses: paambaati/codeclimate-action@v2.3.0
36
+ - name: Run test with Rails ${{ matrix.rails_version }}
37
+ run: bundle exec rake
38
+
39
+ - name: Publish Test Coverage
40
+ uses: paambaati/codeclimate-action@v2.6.0
38
41
  env:
39
- CC_TEST_REPORTER_ID: ${{secrets.CC_TEST_REPORTER_ID}}
42
+ CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
43
+ if: ${{ env.CC_TEST_REPORTER_ID != '' }}
40
44
  with:
41
- coverageCommand: bundle exec rake
45
+ # the coverage result should already be generated by the previous step
46
+ # so we don't need to provide and command in the step
47
+ # this is just a placeholder to avoid it run the default `yarn coverage` command
48
+ coverageCommand: ruby -v
42
49
  debug: true
@@ -0,0 +1,210 @@
1
+ # Changelog
2
+
3
+ ## [v0.5.3](https://github.com/st0012/tapping_device/tree/v0.5.3) (2020-06-21)
4
+
5
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.5.2...v0.5.3)
6
+
7
+ **Closed issues:**
8
+
9
+ - Global Configuration [\#46](https://github.com/st0012/tapping_device/issues/46)
10
+ - Support write\_\* helpers [\#44](https://github.com/st0012/tapping_device/issues/44)
11
+ - Use Method\#source to replace Payload\#method\_head’s implementation [\#19](https://github.com/st0012/tapping_device/issues/19)
12
+
13
+ **Merged pull requests:**
14
+
15
+ - Support Global Configuration [\#48](https://github.com/st0012/tapping_device/pull/48) ([st0012](https://github.com/st0012))
16
+ - Support write\_\* helpers [\#47](https://github.com/st0012/tapping_device/pull/47) ([st0012](https://github.com/st0012))
17
+ - Hijack attr methods with `hijack\_attr\_methods` option [\#45](https://github.com/st0012/tapping_device/pull/45) ([st0012](https://github.com/st0012))
18
+
19
+ ## [v0.5.2](https://github.com/st0012/tapping_device/tree/v0.5.2) (2020-06-10)
20
+
21
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.5.1...v0.5.2)
22
+
23
+ **Closed issues:**
24
+
25
+ - Add print\_mutations [\#41](https://github.com/st0012/tapping_device/issues/41)
26
+ - Add tap\_on\_mutation! [\#18](https://github.com/st0012/tapping_device/issues/18)
27
+
28
+ **Merged pull requests:**
29
+
30
+ - Print mutations [\#43](https://github.com/st0012/tapping_device/pull/43) ([st0012](https://github.com/st0012))
31
+ - Refactorings [\#42](https://github.com/st0012/tapping_device/pull/42) ([st0012](https://github.com/st0012))
32
+
33
+ ## [v0.5.1](https://github.com/st0012/tapping_device/tree/v0.5.1) (2020-06-07)
34
+
35
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.5.0...v0.5.1)
36
+
37
+ **Fixed bugs:**
38
+
39
+ - Filter Out Entries From TappingDevice [\#35](https://github.com/st0012/tapping_device/issues/35)
40
+
41
+ **Merged pull requests:**
42
+
43
+ - Update GitHub Actions Configuration [\#40](https://github.com/st0012/tapping_device/pull/40) ([st0012](https://github.com/st0012))
44
+ - Fix typo: Guadian -\> Guardian [\#39](https://github.com/st0012/tapping_device/pull/39) ([skade](https://github.com/skade))
45
+ - Filter out calls about TappingDevice [\#38](https://github.com/st0012/tapping_device/pull/38) ([st0012](https://github.com/st0012))
46
+ - Drop tap\_sql! [\#37](https://github.com/st0012/tapping_device/pull/37) ([st0012](https://github.com/st0012))
47
+ - Add CollectionProxy class [\#36](https://github.com/st0012/tapping_device/pull/36) ([st0012](https://github.com/st0012))
48
+
49
+ ## [v0.5.0](https://github.com/st0012/tapping_device/tree/v0.5.0) (2020-05-25)
50
+
51
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.11...v0.5.0)
52
+
53
+ **Closed issues:**
54
+
55
+ - Colorize output of tracing helpers [\#25](https://github.com/st0012/tapping_device/issues/25)
56
+
57
+ **Merged pull requests:**
58
+
59
+ - Update README.md [\#34](https://github.com/st0012/tapping_device/pull/34) ([st0012](https://github.com/st0012))
60
+ - Colorize output [\#33](https://github.com/st0012/tapping_device/pull/33) ([st0012](https://github.com/st0012))
61
+ - Add TappingDevice\#with to register a with condition [\#32](https://github.com/st0012/tapping_device/pull/32) ([st0012](https://github.com/st0012))
62
+
63
+ ## [v0.4.11](https://github.com/st0012/tapping_device/tree/v0.4.11) (2020-04-19)
64
+
65
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.10...v0.4.11)
66
+
67
+ **Merged pull requests:**
68
+
69
+ - Update rake requirement from ~\> 10.0 to ~\> 13.0 [\#31](https://github.com/st0012/tapping_device/pull/31) ([dependabot[bot]](https://github.com/apps/dependabot))
70
+
71
+ ## [v0.4.10](https://github.com/st0012/tapping_device/tree/v0.4.10) (2020-02-05)
72
+
73
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.9...v0.4.10)
74
+
75
+ **Implemented enhancements:**
76
+
77
+ - Usability improvements [\#30](https://github.com/st0012/tapping_device/pull/30) ([st0012](https://github.com/st0012))
78
+
79
+ **Merged pull requests:**
80
+
81
+ - Fix tap\_init!'s payload content [\#29](https://github.com/st0012/tapping_device/pull/29) ([st0012](https://github.com/st0012))
82
+ - Refactorings and fixes [\#28](https://github.com/st0012/tapping_device/pull/28) ([st0012](https://github.com/st0012))
83
+
84
+ ## [v0.4.9](https://github.com/st0012/tapping_device/tree/v0.4.9) (2020-01-20)
85
+
86
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.8...v0.4.9)
87
+
88
+ **Implemented enhancements:**
89
+
90
+ - Improve detail\_call\_info's output format [\#27](https://github.com/st0012/tapping_device/pull/27) ([st0012](https://github.com/st0012))
91
+
92
+ ## [v0.4.8](https://github.com/st0012/tapping_device/tree/v0.4.8) (2020-01-05)
93
+
94
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.7...v0.4.8)
95
+
96
+ **Closed issues:**
97
+
98
+ - Provide options for tapping on call or return events [\#23](https://github.com/st0012/tapping_device/issues/23)
99
+
100
+ **Merged pull requests:**
101
+
102
+ - Add tracing helpers [\#24](https://github.com/st0012/tapping_device/pull/24) ([st0012](https://github.com/st0012))
103
+
104
+ ## [v0.4.7](https://github.com/st0012/tapping_device/tree/v0.4.7) (2019-12-29)
105
+
106
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.6...v0.4.7)
107
+
108
+ **Implemented enhancements:**
109
+
110
+ - Config test coverage for codeclimate [\#22](https://github.com/st0012/tapping_device/pull/22) ([st0012](https://github.com/st0012))
111
+
112
+ **Closed issues:**
113
+
114
+ - Support tracking ActiveRecord::Base instances by their ids [\#17](https://github.com/st0012/tapping_device/issues/17)
115
+
116
+ **Merged pull requests:**
117
+
118
+ - Refactor tests and some minor fixes [\#21](https://github.com/st0012/tapping_device/pull/21) ([st0012](https://github.com/st0012))
119
+ - Support track\_as\_records option [\#20](https://github.com/st0012/tapping_device/pull/20) ([st0012](https://github.com/st0012))
120
+
121
+ ## [v0.4.6](https://github.com/st0012/tapping_device/tree/v0.4.6) (2019-12-25)
122
+
123
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.5...v0.4.6)
124
+
125
+ **Merged pull requests:**
126
+
127
+ - Add TappingDevice\#and\_print method [\#16](https://github.com/st0012/tapping_device/pull/16) ([st0012](https://github.com/st0012))
128
+ - Add Payload\#detail\_call\_info and improve method\_name's format [\#15](https://github.com/st0012/tapping_device/pull/15) ([st0012](https://github.com/st0012))
129
+
130
+ ## [v0.4.5](https://github.com/st0012/tapping_device/tree/v0.4.5) (2019-12-15)
131
+
132
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.4...v0.4.5)
133
+
134
+ ## [v0.4.4](https://github.com/st0012/tapping_device/tree/v0.4.4) (2019-12-15)
135
+
136
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.3...v0.4.4)
137
+
138
+ **Merged pull requests:**
139
+
140
+ - Implement tap\_passed! [\#14](https://github.com/st0012/tapping_device/pull/14) ([st0012](https://github.com/st0012))
141
+
142
+ ## [v0.4.3](https://github.com/st0012/tapping_device/tree/v0.4.3) (2019-12-09)
143
+
144
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.2...v0.4.3)
145
+
146
+ ## [v0.4.2](https://github.com/st0012/tapping_device/tree/v0.4.2) (2019-12-09)
147
+
148
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.1...v0.4.2)
149
+
150
+ **Merged pull requests:**
151
+
152
+ - Refactor tap\_sql! [\#13](https://github.com/st0012/tapping_device/pull/13) ([st0012](https://github.com/st0012))
153
+ - Improve tap sql [\#12](https://github.com/st0012/tapping_device/pull/12) ([st0012](https://github.com/st0012))
154
+
155
+ ## [v0.4.1](https://github.com/st0012/tapping_device/tree/v0.4.1) (2019-12-06)
156
+
157
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.4.0...v0.4.1)
158
+
159
+ **Merged pull requests:**
160
+
161
+ - Add TappingDevice::Payload class [\#11](https://github.com/st0012/tapping_device/pull/11) ([st0012](https://github.com/st0012))
162
+
163
+ ## [v0.4.0](https://github.com/st0012/tapping_device/tree/v0.4.0) (2019-11-25)
164
+
165
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.3.0...v0.4.0)
166
+
167
+ **Merged pull requests:**
168
+
169
+ - Support tap\_sql! [\#10](https://github.com/st0012/tapping_device/pull/10) ([st0012](https://github.com/st0012))
170
+ - Minor adjustment [\#9](https://github.com/st0012/tapping_device/pull/9) ([NickWarm](https://github.com/NickWarm))
171
+
172
+ ## [v0.3.0](https://github.com/st0012/tapping_device/tree/v0.3.0) (2019-11-03)
173
+
174
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.2.0...v0.3.0)
175
+
176
+ **Implemented enhancements:**
177
+
178
+ - Largely improve performance by fixing bad design [\#8](https://github.com/st0012/tapping_device/pull/8) ([st0012](https://github.com/st0012))
179
+
180
+ ## [v0.2.0](https://github.com/st0012/tapping_device/tree/v0.2.0) (2019-11-02)
181
+
182
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.1.1...v0.2.0)
183
+
184
+ **Implemented enhancements:**
185
+
186
+ - Add Device class [\#3](https://github.com/st0012/tapping_device/pull/3) ([st0012](https://github.com/st0012))
187
+
188
+ **Merged pull requests:**
189
+
190
+ - Remove tapping\_deivce/device.rb [\#7](https://github.com/st0012/tapping_device/pull/7) ([st0012](https://github.com/st0012))
191
+ - Reduce namespace [\#6](https://github.com/st0012/tapping_device/pull/6) ([st0012](https://github.com/st0012))
192
+ - Register and control all devices from Device class [\#5](https://github.com/st0012/tapping_device/pull/5) ([st0012](https://github.com/st0012))
193
+ - Support `TappingDevice::Device\#stop\_when` [\#4](https://github.com/st0012/tapping_device/pull/4) ([st0012](https://github.com/st0012))
194
+
195
+ ## [v0.1.1](https://github.com/st0012/tapping_device/tree/v0.1.1) (2019-10-20)
196
+
197
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/v0.1.0...v0.1.1)
198
+
199
+ **Implemented enhancements:**
200
+
201
+ - More filters, Refactoring and Readme update [\#2](https://github.com/st0012/tapping_device/pull/2) ([st0012](https://github.com/st0012))
202
+ - Support tapping ActiveRecord class/instance [\#1](https://github.com/st0012/tapping_device/pull/1) ([st0012](https://github.com/st0012))
203
+
204
+ ## [v0.1.0](https://github.com/st0012/tapping_device/tree/v0.1.0) (2019-10-19)
205
+
206
+ [Full Changelog](https://github.com/st0012/tapping_device/compare/61039c87a55c664661b788e24311e263b28a3ee8...v0.1.0)
207
+
208
+
209
+
210
+ \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
@@ -1,36 +1,38 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tapping_device (0.4.11)
4
+ tapping_device (0.5.4)
5
5
  activerecord (>= 5.2)
6
+ activesupport
7
+ pry
6
8
 
7
9
  GEM
8
10
  remote: https://rubygems.org/
9
11
  specs:
10
- activemodel (6.0.2.2)
11
- activesupport (= 6.0.2.2)
12
- activerecord (6.0.2.2)
13
- activemodel (= 6.0.2.2)
14
- activesupport (= 6.0.2.2)
15
- activesupport (6.0.2.2)
12
+ activemodel (6.0.3.2)
13
+ activesupport (= 6.0.3.2)
14
+ activerecord (6.0.3.2)
15
+ activemodel (= 6.0.3.2)
16
+ activesupport (= 6.0.3.2)
17
+ activesupport (6.0.3.2)
16
18
  concurrent-ruby (~> 1.0, >= 1.0.2)
17
19
  i18n (>= 0.7, < 2)
18
20
  minitest (~> 5.1)
19
21
  tzinfo (~> 1.1)
20
- zeitwerk (~> 2.2)
21
- coderay (1.1.2)
22
+ zeitwerk (~> 2.2, >= 2.2.2)
23
+ coderay (1.1.3)
22
24
  concurrent-ruby (1.1.6)
23
25
  database_cleaner (1.7.0)
24
26
  diff-lcs (1.3)
25
27
  docile (1.3.2)
26
- i18n (1.8.2)
28
+ i18n (1.8.3)
27
29
  concurrent-ruby (~> 1.0)
28
30
  json (2.3.0)
29
- method_source (0.9.2)
30
- minitest (5.14.0)
31
- pry (0.12.2)
32
- coderay (~> 1.1.0)
33
- method_source (~> 0.9.0)
31
+ method_source (1.0.0)
32
+ minitest (5.14.1)
33
+ pry (0.13.1)
34
+ coderay (~> 1.1)
35
+ method_source (~> 1.0)
34
36
  rake (13.0.1)
35
37
  rspec (3.8.0)
36
38
  rspec-core (~> 3.8.0)
@@ -54,7 +56,7 @@ GEM
54
56
  thread_safe (0.3.6)
55
57
  tzinfo (1.2.7)
56
58
  thread_safe (~> 0.1)
57
- zeitwerk (2.3.0)
59
+ zeitwerk (2.3.1)
58
60
 
59
61
  PLATFORMS
60
62
  ruby
@@ -62,7 +64,6 @@ PLATFORMS
62
64
  DEPENDENCIES
63
65
  bundler (~> 2.0)
64
66
  database_cleaner
65
- pry
66
67
  rake (~> 13.0)
67
68
  rspec (~> 3.0)
68
69
  simplecov (= 0.17.1)
data/README.md CHANGED
@@ -6,417 +6,292 @@
6
6
  [![Test Coverage](https://api.codeclimate.com/v1/badges/3e3732a6983785bccdbd/test_coverage)](https://codeclimate.com/github/st0012/tapping_device/test_coverage)
7
7
  [![Open Source Helpers](https://www.codetriage.com/st0012/tapping_device/badges/users.svg)](https://www.codetriage.com/st0012/tapping_device)
8
8
 
9
- ## Related Posts
10
- - [Optimize Your Debugging Process With Object-Oriented Tracing and tapping_device](http://bit.ly/object-oriented-tracing)
11
- - [Debug Rails issues effectively with tapping_device](https://dev.to/st0012/debug-rails-issues-effectively-with-tappingdevice-c7c)
12
- - [Want to know more about your Rails app? Tap on your objects!](https://dev.to/st0012/want-to-know-more-about-your-rails-app-tap-on-your-objects-bd3)
13
9
 
10
+ ## Introduction
11
+ As the name states, `TappingDevice` allows you to secretly listen to different events of an object:
14
12
 
15
- ## Table of Content
16
- - [Introduction](#introduction)
17
- - [Print Object’s Traces](print-objects-traces)
18
- - [Track Calls that Generates SQL Queries](#track-calls-that-generates-sql-queries)
19
- - [Installation](#installation)
20
- - [Usages](#usages)
21
- - Tracing Helpers
22
- - [print_traces](#print_traces)
23
- - [print_calls_in_detail](#print_calls_in_detail)
24
- - Tapping Methods
25
- - [tap_init!](#tap_init)
26
- - [tap_on!](#tap_on)
27
- - [tap_passed!](#tap_passed)
28
- - [tap_assoc!](#tap_assoc)
29
- - [tap_sql!](#tap_sql)
30
- - [Options](#options)
31
- - [Payload](#payload-of-the-call)
32
- - [Advance Usages](#advance-usages)
13
+ - `Method Calls` - what does the object do
14
+ - `Traces` - how is the object used by the application
15
+ - `State Mutations` - what happens inside the object
33
16
 
34
- ## Introduction
35
- `tapping_device` is a debugging tool built based on a concept called `object-oriented tracing` and on top of Ruby's `TracePoint` class. It allows you to inspect an object’s behavior, and thus build the program’s execution path for later debugging. Here’s a post to explain how to use `object-oriented tracing` and this gem to improve your debugging workflow: [Optimize Your Debugging Process With Object-Oriented Tracing and tapping_device](http://bit.ly/object-oriented-tracing).
17
+ After collecting the events, `TappingDevice` will output them in a nice, readable format to either stdout or a file.
36
18
 
37
- Sample usage:
19
+ **Ultimately, its goal is to let you know all the information you need for debugging with just 1 line of code.**
38
20
 
39
- ### Print Object’s Traces
21
+ ## Usages
40
22
 
41
- Let your objects report to you, so you don’t need to guess how they work!
23
+ ### Track Method Calls
42
24
 
43
- ```ruby
44
- class OrdersController < ApplicationController
45
- def create
46
- @cart = Cart.find(order_params[:cart_id])
47
- print_traces(@cart, exclude_by_paths: [/gems/])
48
- @order = OrderCreationService.new.perform(@cart)
49
- end
50
- ```
25
+ By tracking an object's method calls, you'll be able to observe the object's behavior very easily
51
26
 
52
- ```
53
- Passed as 'cart' in 'OrderCreationService#perform' at /Users/st0012/projects/tapping_device-demo/app/controllers/orders_controller.rb:10
54
- Passed as 'cart' in 'OrderCreationService#validate_cart' at /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:8
55
- Called :reserved_until FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:18
56
- Called :errors FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:9
57
- Passed as 'cart' in 'OrderCreationService#apply_discount' at /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:10
58
- Called :apply_discount FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:24
59
- ……
60
- ```
27
+ <img src="https://github.com/st0012/tapping_device/blob/master/images/print_calls.png" alt="image of print_calls output" width="50%">
61
28
 
62
- (Also see [print_calls_in_detail](#print_calls_in_detail))
29
+ Each entry consists of 5 pieces of information:
30
+ - method name
31
+ - source of the method
32
+ - call site
33
+ - arguments
34
+ - return value
63
35
 
36
+ ![explanation of individual entry](https://github.com/st0012/tapping_device/blob/master/images/print_calls%20-%20single%20entry.png)
64
37
 
65
- However, depending on the size of your application, tapping any object could **harm the performance significantly**. **Don't use this on production**
38
+ #### Helpers
66
39
 
67
- ## Installation
68
- Add this line to your application's Gemfile:
40
+ - `print_calls(object)` - prints the result to stdout
41
+ - `write_calls(object, log_file: "file_name")` - writes the result to a file
42
+ - the default file is `/tmp/tapping_device.log`, but you can change it with `log_file: "new_path"` option
69
43
 
70
- ```ruby
71
- gem 'tapping_device', group: :development
72
- ```
44
+ #### Use Cases
45
+ - Understand a service object/form object's behavior
46
+ - Debug a messy controller
73
47
 
74
- And then execute:
48
+ ### Track Traces
75
49
 
76
- ```
77
- $ bundle
78
- ```
50
+ By tracking an object's traces, you'll be able to observe the object's journey in your application
79
51
 
80
- Or install it yourself as:
52
+ ![image of print_traces output](https://github.com/st0012/tapping_device/blob/master/images/print_traces.png)
81
53
 
82
- ```
83
- $ gem install tapping_device
84
- ```
54
+ #### Helpers
85
55
 
86
- ## Usages
56
+ - `print_traces(object)` - prints the result to stdout
57
+ - `write_traces(object, log_file: "file_name")` - writes the result to a file
58
+ - the default file is `/tmp/tapping_device.log`, but you can change it with `log_file: "new_path"` option
87
59
 
88
- ### print_traces
60
+ #### Use Cases
61
+ - Debug argument related issues
62
+ - Understand how a library uses your objects
89
63
 
90
- It prints the object's trace. It's like mounting a GPS tracker + a spy camera on your object, so you can inspect your program through the object's eyes.
64
+ ### Track State Mutations
91
65
 
92
- ```ruby
93
- class OrdersController < ApplicationController
94
- def create
95
- @cart = Cart.find(order_params[:cart_id])
96
- print_traces(@cart, exclude_by_paths: [/gems/])
97
- @order = OrderCreationService.new.perform(@cart)
98
- end
99
- ```
66
+ By tracking an object's traces, you'll be able to observe the state changes happen inside the object between each method call
100
67
 
101
- ```
102
- Passed as 'cart' in 'OrderCreationService#perform' at /Users/st0012/projects/tapping_device-demo/app/controllers/orders_controller.rb:10
103
- Passed as 'cart' in 'OrderCreationService#validate_cart' at /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:8
104
- Called :reserved_until FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:18
105
- Called :errors FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:9
106
- Passed as 'cart' in 'OrderCreationService#apply_discount' at /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:10
107
- Called :apply_discount FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:24
108
- ……
109
- ```
68
+ <img src="https://github.com/st0012/tapping_device/blob/master/images/print_mutations.png" alt="image of print_mutations output" width="50%">
69
+
70
+ #### Helpers
71
+
72
+ - `print_mutations(object)` - prints the result to stdout
73
+ - `write_mutations(object, log_file: "file_name")` - writes the result to a file
74
+ - the default file is `/tmp/tapping_device.log`, but you can change it with `log_file: "new_path"` option
75
+
76
+ #### Use Cases
77
+ - Debug state related issues
78
+ - Debug memoization issues
79
+
80
+ ### Track All Instances Of A Class
110
81
 
111
- ### print_calls_in_detail
82
+ It's not always easy to directly access the objects we want to track, especially when they're managed by a library (e.g. `ActiveRecord::Relation`). In such cases, you can use these helpers to track the class's instances:
112
83
 
113
- It prints the object's calls in detail (including call location, arguments, and return value). It's useful for observing an object's behavior when debugging.
84
+ - `print_instance_calls(ObjectKlass)`
85
+ - `print_instance_traces(ObjectKlass)`
86
+ - `print_instance_mutations(ObjectKlass)`
87
+ - `write_instance_calls(ObjectKlass)`
88
+ - `write_instance_traces(ObjectKlass)`
89
+ - `write_instance_mutations(ObjectKlass)`
114
90
 
115
- #### Options
116
- - `inspect:` - will print objects with `#inspect` instead of `#to_s` if set to `true` (very noisy when having large objects). Default is `false`.
91
+
92
+ ### Use `with_HELPER_NAME` for chained method calls
93
+
94
+ In Ruby programs, we often chain multiple methods together like this:
117
95
 
118
96
  ```ruby
119
- class OrdersController < ApplicationController
120
- def create
121
- @cart = Cart.find(order_params[:cart_id])
122
- service = OrderCreationService.new
123
- print_calls_in_detail(service)
124
- @order = service.perform(@cart)
125
- end
97
+ SomeService.new(params).perform
126
98
  ```
127
99
 
128
- ```
129
- :validate_cart # OrderCreationService
130
- <= {:cart=>#<Cart id: 1, total: 10, customer_id: 1, promotion_id: nil, reserved_until: nil, created_at: "2020-01-05 09:48:28", updated_at: "2020-01-05 09:48:28">}
131
- => nil
132
- FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:8
133
- :apply_discount # OrderCreationService
134
- <= {:cart=>#<Cart id: 1, total: 5, customer_id: 1, promotion_id: 1, reserved_until: nil, created_at: "2020-01-05 09:48:28", updated_at: "2020-01-05 09:48:28">, :promotion=>#<Promotion id: 1, amount: 0.5e1, customer_id: nil, created_at: "2020-01-05 09:48:28", updated_at: "2020-01-05 09:48:28">}
135
- => true
136
- FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:10
137
- :create_order # OrderCreationService
138
- <= {:cart=>#<Cart id: 1, total: 5, customer_id: 1, promotion_id: 1, reserved_until: nil, created_at: "2020-01-05 09:48:28", updated_at: "2020-01-05 09:48:28">}
139
- => #<Order:0x00007f9ebcb17f08>
140
- FROM /Users/st0012/projects/tapping_device-demo/app/services/order_creation_service.rb:11
141
- :perform # OrderCreationService
142
- <= {:cart=>#<Cart id: 1, total: 5, customer_id: 1, promotion_id: 1, reserved_until: nil, created_at: "2020-01-05 09:48:28", updated_at: "2020-01-05 09:48:28">, :promotion=>#<Promotion id: 1, amount: 0.5e1, customer_id: nil, created_at: "2020-01-05 09:48:28", updated_at: "2020-01-05 09:48:28">}
143
- => #<Order:0x00007f9ebcb17f08>
144
- FROM /Users/st0012/projects/tapping_device-demo/app/controllers/orders_controller.rb:11
145
- ```
100
+ And to debug it, we'll need to break the method chain into
146
101
 
147
- The output's order might look strange. This is because `tapping_device` needs to wait for the call to return in order to have its return value.
102
+ ```ruby
103
+ service = SomeService.new(params)
104
+ print_calls(service, options)
105
+ service.perform
106
+ ```
148
107
 
149
- ### tap_init!
108
+ This kind of code changes are usually annoying, and that's one of the problems I want to solve with `TappingDevice`.
150
109
 
151
- `tap_init!(class)` - tracks a class’ instance initialization
110
+ So here's another option, just insert a `with_HELPER_NAME` call in between:
152
111
 
153
112
  ```ruby
154
- calls = []
155
- tap_init!(Student) do |payload|
156
- calls << [payload[:method_name], payload[:arguments]]
157
- end
113
+ SomeService.new(params).with_print_calls(options).perform
114
+ ```
158
115
 
159
- Student.new("Stan", 18)
160
- Student.new("Jane", 23)
116
+ And it'll behave exactly like
161
117
 
162
- puts(calls.to_s) #=> [[:initialize, {:name=>"Stan", :age=>18}], [:initialize, {:name=>"Jane", :age=>23}]]
118
+ ```ruby
119
+ service = SomeService.new(params)
120
+ print_calls(service, options)
121
+ service.perform
163
122
  ```
164
123
 
165
- ### tap_on!
166
-
167
- `tap_on!(object)` - tracks any calls received by the object.
124
+ ## Installation
125
+ Add this line to your application's Gemfile:
168
126
 
169
127
  ```ruby
170
- class PostsController < ApplicationController
171
- before_action :set_post, only: [:show, :edit, :update, :destroy]
128
+ gem 'tapping_device', group: :development
129
+ ```
172
130
 
173
- def show
174
- tap_on!(@post).and_print(:method_name_and_location)
175
- end
176
- end
131
+ And then execute:
132
+
133
+ ```
134
+ $ bundle
177
135
  ```
178
136
 
179
- And you can see these in log:
137
+ Or install it directly:
180
138
 
181
139
  ```
182
- name FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:5
183
- user_id FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:10
184
- to_param FROM /RUBY_PATH/gems/2.6.0/gems/actionpack-5.2.0/lib/action_dispatch/routing/route_set.rb:236
140
+ $ gem install tapping_device
185
141
  ```
186
142
 
187
- Also check the `track_as_records` option if you want to track `ActiveRecord` records.
143
+ **Depending on the size of your application, `TappingDevice` could harm the performance significantly. So make sure you don't put it inside the production group**
188
144
 
189
- ### tap_passed!
190
145
 
191
- `tap_passed!(target)` tracks method calls that **takes the target as its argument**. This is particularly useful when debugging libraries. It saves your time from jumping between files and check which path the object will go.
146
+ ## Advance Usages & Options
147
+
148
+ ### Add Conditions With `.with`
149
+
150
+ Sometimes we don't need to know all the calls or traces of an object; we just want some of them. In those cases, we can chain the helpers with `.with` to filter the calls/traces.
192
151
 
193
152
  ```ruby
194
- class PostsController < ApplicationController
195
- # GET /posts/new
196
- def new
197
- @post = Post.new
198
-
199
- tap_passed!(@post) do |payload|
200
- puts(payload.passed_at(with_method_head: true))
201
- end
202
- end
153
+ # only prints calls with name matches /foo/
154
+ print_calls(object).with do |payload|
155
+ payload.method_name.to_s.match?(/foo/)
203
156
  end
204
157
  ```
205
158
 
206
- ```
207
- Passed as 'record' in method ':polymorphic_mapping'
208
- > def polymorphic_mapping(record)
209
- at /Users/st0012/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/polymorphic_routes.rb:131
210
- Passed as 'klass' in method ':get_method_for_class'
211
- > def get_method_for_class(klass)
212
- at /Users/st0012/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/polymorphic_routes.rb:269
213
- Passed as 'record' in method ':handle_model'
214
- > def handle_model(record)
215
- at /Users/st0012/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/polymorphic_routes.rb:227
216
- Passed as 'record_or_hash_or_array' in method ':polymorphic_method'
217
- > def self.polymorphic_method(recipient, record_or_hash_or_array, action, type, options)
218
- at /Users/st0012/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/polymorphic_routes.rb:139
219
- ```
220
-
221
- ### tap_assoc!
159
+ ### Options
222
160
 
223
- `tap_assoc!(activerecord_object)` tracks association calls on a record, like `post.comments`
161
+ There are many options you can pass when using a helper method. You can list all available options and their default value with
224
162
 
225
163
  ```ruby
226
- tap_assoc!(order).and_print(:method_name_and_location)
164
+ TappingDevice::Configurable::DEFAULTS #=> {
165
+ :filter_by_paths=>[],
166
+ :exclude_by_paths=>[],
167
+ :with_trace_to=>50,
168
+ :event_type=>:return,
169
+ :hijack_attr_methods=>false,
170
+ :track_as_records=>false,
171
+ :inspect=>false,
172
+ :colorize=>true,
173
+ :log_file=>"/tmp/tapping_device.log"
174
+ }
227
175
  ```
228
176
 
229
- ```
230
- payments FROM /RUBY_PATH/gems/2.6.0/gems/jsonapi-resources-0.9.10/lib/jsonapi/resource.rb:124
231
- line_items FROM /MY_PROJECT/app/models/line_item_container_helpers.rb:44
232
- effective_line_items FROM /MY_PROJECT/app/models/line_item_container_helpers.rb:110
233
- amending_orders FROM /MY_PROJECT/app/models/order.rb:385
234
- amends_order FROM /MY_PROJECT/app/models/order.rb:432
235
- ```
177
+ Here are some commonly used options:
236
178
 
237
- ### tap_sql!
179
+ #### `colorize: false`
180
+
181
+ - default: `true`
182
+
183
+ By default `print_calls` and `print_traces` colorize their output. If you don't want the colors, you can use `colorize: false` to disable it.
238
184
 
239
- `tap_sql!(anything_that_generates_sql_queries)` tracks sql queries generated from the target
240
185
 
241
186
  ```ruby
242
- class PostsController < ApplicationController
243
- def index
244
- # simulate current_user
245
- @current_user = User.last
246
- # reusable ActiveRecord::Relation
247
- @posts = Post.all
248
-
249
- tap_sql!(@posts) do |payload|
250
- puts("Method: #{payload[:method_name]} generated sql: #{payload[:sql]} from #{payload[:filepath]}:#{payload[:line_number]}")
251
- end
252
- end
253
- end
187
+ print_calls(object, colorize: false)
254
188
  ```
255
189
 
256
- ```erb
257
- <h1>Posts (<%= @posts.count %>)</h1>
258
- ......
259
- <% @posts.each do |post| %>
260
- ......
261
- <% end %>
262
- ......
263
- <p>Posts created by you: <%= @posts.where(user: @current_user).count %></p>
264
- ```
265
190
 
266
- ```
267
- Method: count generated sql: SELECT COUNT(*) FROM "posts" from /PROJECT_PATH/rails-6-sample/app/views/posts/index.html.erb:3
268
- Method: each generated sql: SELECT "posts".* FROM "posts" from /PROJECT_PATH/rails-6-sample/app/views/posts/index.html.erb:16
269
- Method: count generated sql: SELECT COUNT(*) FROM "posts" WHERE "posts"."user_id" = ? from /PROJECT_PATH/rails-6-sample/app/views/posts/index.html.erb:31
270
- ```
191
+ #### `inspect: true`
271
192
 
193
+ - default: `false`
272
194
 
273
- ### Options
274
- #### with_trace_to
275
- It takes an integer as the number of traces we want to put into `trace`. Default is `nil`, so `trace` would be empty.
195
+ As you might have noticed, all the objects are converted into strings with `#to_s` instead of `#inspect`. This is because when used on some Rails objects, `#inspect` can generate a significantly larger string than `#to_s`. For example:
276
196
 
277
- ```ruby
278
- stan = Student.new("Stan", 18)
279
- tap_on!(stan, with_trace_to: 5)
280
-
281
- stan.name
282
-
283
- puts(device.calls.first.trace) #=>
284
- /Users/st0012/projects/tapping_device/spec/tapping_device_spec.rb:287:in `block (4 levels) in <top (required)>'
285
- /Users/st0012/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rspec-core-3.8.2/lib/rspec/core/example.rb:257:in `instance_exec'
286
- /Users/st0012/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rspec-core-3.8.2/lib/rspec/core/example.rb:257:in `block in run'
287
- /Users/st0012/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rspec-core-3.8.2/lib/rspec/core/example.rb:503:in `block in with_around_and_singleton_context_hooks'
288
- /Users/st0012/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rspec-core-3.8.2/lib/rspec/core/example.rb:460:in `block in with_around_example_hooks'
289
- /Users/st0012/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rspec-core-3.8.2/lib/rspec/core/hooks.rb:464:in `block in run'
197
+ ``` ruby
198
+ post.to_s #=> #<Post:0x00007f89a55201d0>
199
+ post.inspect #=> #<Post id: 649, user_id: 3, topic_id: 600, post_number: 1, raw: "Hello world", cooked: "<p>Hello world</p>", created_at: "2020-05-24 08:07:29", updated_at: "2020-05-24 08:07:29", reply_to_post_number: nil, reply_count: 0, quote_count: 0, deleted_at: nil, off_topic_count: 0, like_count: 0, incoming_link_count: 0, bookmark_count: 0, score: nil, reads: 0, post_type: 1, sort_order: 1, last_editor_id: 3, hidden: false, hidden_reason_id: nil, notify_moderators_count: 0, spam_count: 0, illegal_count: 0, inappropriate_count: 0, last_version_at: "2020-05-24 08:07:29", user_deleted: false, reply_to_user_id: nil, percent_rank: 1.0, notify_user_count: 0, like_score: 0, deleted_by_id: nil, edit_reason: nil, word_count: 2, version: 1, cook_method: 1, wiki: false, baked_at: "2020-05-24 08:07:29", baked_version: 2, hidden_at: nil, self_edits: 0, reply_quoted: false, via_email: false, raw_email: nil, public_version: 1, action_code: nil, image_url: nil, locked_by_id: nil, image_upload_id: nil>
290
200
  ```
291
201
 
292
- #### track_as_records
293
- It makes the device to track objects as they are ActiveRecord instances. For example:
202
+ #### `hijack_attr_methods: true`
203
+
204
+ - default: `false`
205
+ - except for `tap_mutation!` and `print_mutations`
206
+
207
+ Because `TracePoint` doesn't track methods generated by `attr_*` helpers (see [this issue](https://bugs.ruby-lang.org/issues/16383) for more info), we need to redefine those methods with the normal method definition.
208
+
209
+ For example, it generates
294
210
 
295
211
  ```ruby
296
- tap_on!(@post, track_as_records: true)
297
- post = Post.find(@post.id) # same record but a different object
298
- post.title #=> this call will be recorded as well
212
+ def name=(val)
213
+ @name = val
214
+ end
299
215
  ```
300
216
 
301
- #### exclude_by_paths
302
- It takes an array of call path patterns that we want to skip. This could be very helpful when working on a large project like Rails applications.
217
+ for
303
218
 
304
219
  ```ruby
305
- tap_on!(@post, exclude_by_paths: [/active_record/]).and_print(:method_name_and_location)
220
+ attr_writer :name
306
221
  ```
307
222
 
308
- ```
309
- _read_attribute FROM /RUBY_PATH/gems/2.6.0/gems/activerecord-5.2.0/lib/active_record/attribute_methods/read.rb:40
310
- name FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:5
311
- _read_attribute FROM /RUBY_PATH/gems/2.6.0/gems/activerecord-5.2.0/lib/active_record/attribute_methods/read.rb:40
312
- user_id FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:10
313
- .......
223
+ This hack will only be applied to the target instance with `instance_eval`. So other instances of the class remain untouched.
314
224
 
315
- # versus
225
+ The default is `false` because
316
226
 
317
- name FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:5
318
- user_id FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:10
319
- to_param FROM /RUBY_PATH/gems/2.6.0/gems/actionpack-5.2.0/lib/action_dispatch/routing/route_set.rb:236
320
- ```
227
+ 1. Checking what methods are generated by `attr_*` helpers isn't free. It's an `O(n)` operation, where `n` is the number of methods the target object has.
228
+ 2. It's still unclear if this hack safe enough for most applications.
321
229
 
322
- #### filter_by_paths
323
-
324
- Like `exclude_by_paths`, but work in the opposite way.
325
-
326
-
327
- ### Payload of The Call
328
- All tapping methods (start with `tap_`) takes a block and yield a `Payload` object as a block argument. It responds to
329
-
330
- - `target` - the target for `tap_x` call
331
- - `receiver` - the receiver object
332
- - `method_name` - method’s name (symbol)
333
- - e.g. `:name`
334
- - `method_object` - the method object that's being called. It might be `nil` in some edge cases.
335
- - `arguments` - arguments of the method call
336
- - e.g. `{name: “Stan”, age: 25}`
337
- - `return_value` - return value of the method call
338
- - `filepath` - path to the file that performs the method call
339
- - `line_number`
340
- - `defined_class` - in which class that defines the method being called
341
- - `trace` - stack trace of the call. Default is an empty array unless `with_trace_to` option is set
342
- - `sql` - sql that generated from the call (only present in `tap_sql!` payloads)
343
- - `tp` - trace point object of this call
344
-
345
-
346
- #### Symbols for Payload Helpers
347
- - `FROM` for method call’s location
348
- - `<=` for arguments
349
- - `=>` for return value
350
- - `@` for defined class
351
-
352
- #### Payload Helpers
353
- - `method_name_and_location` - `initialize FROM /PROJECT_PATH/tapping_device/spec/payload_spec.rb:7`
354
- - `method_name_and_arguments` - `initialize <= {:name=>\"Stan\", :age=>25}`
355
- - `method_name_and_return_value` - `ten => 10`
356
- - `method_name_and_defined_class` - `initialize @ Student`
357
- - `passed_at` -
358
- ```
359
- Passed as 'object' in method ':initialize'
360
- at /Users/st0012/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionview-6.0.0/lib/action_view/helpers/tags/label.rb:60
361
- ```
362
230
 
363
- You can also set `passed_at(with_method_head: true)` to see the method's head.
231
+ #### `ignore_private`
364
232
 
365
- ```
366
- Passed as 'object' in method ':initialize'
367
- > def initialize(template_object, object_name, method_name, object, tag_value)
368
- at /Users/st0012/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionview-6.0.0/lib/action_view/helpers/tags/label.rb:60
369
- ```
233
+ Sometimes we use many private methods to perform trivial operations, like
370
234
 
371
- - `detail_call_info`
235
+ ```ruby
236
+ class Operation
237
+ def extras
238
+ dig_attribute("extras")
239
+ end
372
240
 
373
- ```
374
- initialize @ Student
375
- <= {:name=>"Stan", :age=>25}
376
- => 25
377
- FROM /Users/st0012/projects/tapping_device/spec/payload_spec.rb:7
378
- ```
241
+ private
379
242
 
380
- ### Advance Usages
243
+ def data
244
+ @data
245
+ end
381
246
 
382
- Tapping methods introduced above like `tap_on!` are designed for simple use cases. They're actually short for
247
+ def dig_attribute(attr)
248
+ data.dig("attributes", attr)
249
+ end
250
+ end
251
+ ```
252
+
253
+ And we may not be interested in those method calls. If that's the case, you can use the `ignore_private` option
383
254
 
384
255
  ```ruby
385
- device = TappingDevice.new { # tapping action }
386
- device.tap_on!(object)
256
+ operation = Operation.new(params)
257
+ print_calls(operation, ignore_private: true) #=> only prints the `extras` call
387
258
  ```
388
259
 
389
- And if you want to do some more configurations like stopping them manually or setting stop condition, you must have a `TappingDevie` instance. You can either get them like the above code or save the return value of `tap_*!` method calls.
260
+ #### `only_private`
261
+
262
+ This option does the opposite of the `ignore_private` option does.
263
+
390
264
 
391
- #### Stop tapping
265
+ ### Global Configuration
266
+
267
+ If you don't want to pass options every time you use a helper, you can use global configuration to change the default values:
268
+
269
+ ```ruby
270
+ TappingDevice.config[:colorize] = false
271
+ TappingDevice.config[:hijack_attr_methods] = true
272
+ ```
392
273
 
393
- Once you have a `TappingDevice` instance in hand, you will be able to stop the tapping by
394
- 1. Manually calling `device.stop!`
395
- 2. Setting stop condition with `device.stop_when`, like
274
+ And if you're using Rails, you can put the configs under `config/initializers/tapping_device.rb` like this:
396
275
 
397
276
  ```ruby
398
- device.stop_when do |payload|
399
- device.calls.count >= 10 # stop after gathering 10 calls’ data
277
+ if defined?(TappingDevice)
278
+ TappingDevice.config[:colorize] = false
279
+ TappingDevice.config[:hijack_attr_methods] = true
400
280
  end
401
281
  ```
402
282
 
403
- #### Device states & Managing Devices
404
283
 
405
- Each `TappingDevice` instance can have 3 states:
284
+ ### Lower-Level Helpers
285
+ `print_calls` and `print_traces` aren't the only helpers you can get from `TappingDevice`. They are actually built on top of other helpers, which you can use as well. To know more about them, please check [this page](https://github.com/st0012/tapping_device/wiki/Advance-Usages)
406
286
 
407
- - `Initial` - means the instance is initialized but hasn't tapped on anything.
408
- - `Enabled` - means the instance is tapping on something (has called `tap_*` methods).
409
- - `Disabled` - means the instance has been disabled. It will no longer receive any call info.
410
287
 
411
- When debugging, we may create many device instances and tap objects in several places. Then it'll be quite annoying to manage their states. So `TappingDevice` has several class methods that allows you to manage all `TappingDevice` instances:
288
+ ### Related Blog Posts
289
+ - [Optimize Your Debugging Process With Object-Oriented Tracing and tapping_device](http://bit.ly/object-oriented-tracing)
290
+ - [Debug Rails issues effectively with tapping_device](https://dev.to/st0012/debug-rails-issues-effectively-with-tappingdevice-c7c)
291
+ - [Want to know more about your Rails app? Tap on your objects!](https://dev.to/st0012/want-to-know-more-about-your-rails-app-tap-on-your-objects-bd3)
412
292
 
413
- - `TappingDevice.devices` - Lists all registered devices with `initial` or `enabled` state. Note that any instance that's been stopped will be removed from the list.
414
- - `TappingDevice.stop_all!` - Stops all registered devices and remove them from the `devices` list.
415
- - `TappingDevice.suspend_new!` - Suspends any device instance from changing their state from `initial` to `enabled`. Which means any `tap_*` calls after it will no longer work.
416
- - `TappingDevice.reset!` - Cancels `suspend_new` (if called) and stops/removes all created devices. Useful to reset the environment between test cases.
417
293
 
418
294
  ## Development
419
-
420
295
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
421
296
 
422
297
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
@@ -432,3 +307,4 @@ The gem is available as open-source under the terms of the [MIT License](https:/
432
307
  ## Code of Conduct
433
308
 
434
309
  Everyone interacting in the TappingDevice project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/tapping_device/blob/master/CODE_OF_CONDUCT.md).
310
+