object_tracker 1.2.0 → 2.0.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/lib/object_tracker/tracker_method.rb +36 -0
- data/lib/object_tracker/version.rb +1 -1
- data/lib/object_tracker.rb +93 -101
- data/object_tracker.gemspec +3 -3
- metadata +8 -14
- data/.gitignore +0 -15
- data/Gemfile +0 -4
- data/LICENSE.txt +0 -22
- data/README.md +0 -265
- data/Rakefile +0 -2
- data/bin/console.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a7d0b65299e8afcbd85241099ca20179d143b74
|
4
|
+
data.tar.gz: 03425ae584ea22e6a94d928c9c566d42b3f2984d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6919b9db7a8442104f7b9caa0d388536d3ef368c876c65717ffaa9bd277152397e89ffaf0f86d609f24a54cb861453e8539b7d68cb60c1984ef6fb8d80ead79
|
7
|
+
data.tar.gz: 6209b7936adf4326b0d0c61d24e018fc6bab9e8b1ce6cbd4445533cde6325c718dfc448dde3d687b1646666d24789e5b17878a767620a43469f72f2805c43b4c
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module ObjectTracker
|
2
|
+
class TrackerMethod
|
3
|
+
attr_reader :name, :context
|
4
|
+
|
5
|
+
def initialize(context, name)
|
6
|
+
@name = name
|
7
|
+
@context = context
|
8
|
+
end
|
9
|
+
|
10
|
+
def source
|
11
|
+
return @source if defined? @source
|
12
|
+
@source = source_location
|
13
|
+
@source = @source ? @source.join(':').split('/').last(5).join('/') : 'RUBY CORE'
|
14
|
+
end
|
15
|
+
|
16
|
+
def source_location
|
17
|
+
method_handle = context.method(name)
|
18
|
+
method_handle.source_location if method_handle
|
19
|
+
end
|
20
|
+
|
21
|
+
def display_name
|
22
|
+
return @display_name if defined? @display_name
|
23
|
+
if Class === context || Module === context
|
24
|
+
obj = context
|
25
|
+
prefix = '.'
|
26
|
+
elsif context.class === Class
|
27
|
+
prefix = '.'
|
28
|
+
obj = context.class
|
29
|
+
else
|
30
|
+
prefix = '#'
|
31
|
+
obj = context.class
|
32
|
+
end
|
33
|
+
@display_name = "#{obj.name}#{prefix}#{@name}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/object_tracker.rb
CHANGED
@@ -2,132 +2,124 @@ require 'benchmark'
|
|
2
2
|
require 'object_tracker/version'
|
3
3
|
|
4
4
|
module ObjectTracker
|
5
|
-
|
6
|
-
args.each do |method_name|
|
7
|
-
next if tracking?(method_name) || track_reserved_methods.include?(method_name)
|
8
|
-
if respond_to?(method_name)
|
9
|
-
track!(method_name => track_with_source(self, method_name))
|
10
|
-
elsif respond_to?(:allocate)
|
11
|
-
inst = allocate
|
12
|
-
if inst.respond_to?(method_name)
|
13
|
-
track!(method_name => track_with_source(inst, method_name))
|
14
|
-
else
|
15
|
-
fail UntrackableMethod, method_name
|
16
|
-
end
|
17
|
-
else
|
18
|
-
fail UntrackableMethod, method_name
|
19
|
-
end
|
20
|
-
end
|
21
|
-
nil
|
22
|
-
end
|
5
|
+
autoload :TrackerMethod, 'object_tracker/tracker_method'
|
23
6
|
|
24
|
-
|
25
|
-
|
7
|
+
# @param method_names [Array<Symbol>] method names to track
|
8
|
+
# @option :except [Array<Symbol>] method names to NOT track
|
9
|
+
# @option :before [Proc] proc to call before method execution (e.g. ->(_name, _context, *_args) {})
|
10
|
+
# @option :after [Proc] proc to call after method execution (e.g. ->(_name, _context, *_args) {})
|
11
|
+
def track_all!(method_names = [], **options)
|
12
|
+
ObjectTracker.(self, method_names, **options)
|
13
|
+
self
|
26
14
|
end
|
27
15
|
|
28
|
-
|
29
|
-
|
30
|
-
|
16
|
+
class << self
|
17
|
+
def reserved_tracker_methods
|
18
|
+
@__reserved_methods ||= begin
|
19
|
+
names = [:__send__]
|
20
|
+
names.concat [:default_scope, :current_scope=] if defined?(Rails)
|
21
|
+
names
|
22
|
+
end
|
31
23
|
end
|
32
|
-
nil
|
33
|
-
end
|
34
|
-
|
35
|
-
def track_all!(*args)
|
36
|
-
track_not *args if args.any?
|
37
|
-
track_methods_for(self)
|
38
|
-
track_methods_for(allocate) if respond_to?(:allocate)
|
39
|
-
track!
|
40
24
|
end
|
41
25
|
|
26
|
+
#= Utilities (not extended or mixed in)
|
42
27
|
#
|
43
|
-
#
|
28
|
+
# Tracks method calls to the given object
|
44
29
|
#
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
@__tracked_calls << "#{method_name}"
|
64
|
-
result
|
65
|
-
rescue NoMethodError => e
|
66
|
-
raise e if e.message !~ /no superclass/
|
30
|
+
# @note Alias to .()
|
31
|
+
#
|
32
|
+
# @param obj [Object] class or instance to track
|
33
|
+
# @param method_names [Array<Symbol>] method names to track
|
34
|
+
# @option :except [Array<Symbol>] method names to NOT track
|
35
|
+
# @option :before [Proc] proc to call before method execution (e.g. ->(_name, _context, *_args) {})
|
36
|
+
# @option :after [Proc] proc to call after method execution (e.g. ->(_name, _context, *_args) {})
|
37
|
+
def self.call(obj, method_names = [], except: [], **options)
|
38
|
+
class_methods = []
|
39
|
+
inst_methods = []
|
40
|
+
reserved = obj.respond_to?(:reserved_tracker_methods) ? obj.reserved_tracker_methods : ObjectTracker.reserved_tracker_methods
|
41
|
+
obj_instance = obj.respond_to?(:allocate) ? obj.allocate : obj
|
42
|
+
if Array(method_names).any?
|
43
|
+
Array(method_names).each do |method_name|
|
44
|
+
if obj.methods.include?(method_name)
|
45
|
+
class_methods << TrackerMethod.new(obj, method_name)
|
46
|
+
elsif obj.respond_to?(:instance_method)
|
47
|
+
inst_methods << TrackerMethod.new(obj_instance, method_name)
|
67
48
|
end
|
68
|
-
RUBY
|
69
|
-
end
|
70
|
-
|
71
|
-
mod.module_eval <<-RUBY, __FILE__, __LINE__
|
72
|
-
def self.prepended(base)
|
73
|
-
base.extend(self)
|
74
49
|
end
|
75
|
-
RUBY
|
76
|
-
|
77
|
-
# Handle both instance and class level extension
|
78
|
-
if Class === self
|
79
|
-
prepend(Inspector)
|
80
|
-
prepend(mod)
|
81
50
|
else
|
82
|
-
|
83
|
-
|
51
|
+
if obj.respond_to?(:instance_methods)
|
52
|
+
(obj.instance_methods - reserved - Array(except)).each do |method_name|
|
53
|
+
inst_methods << TrackerMethod.new(obj_instance, method_name)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
(obj.methods - reserved - Array(except)).each do |method_name|
|
57
|
+
class_methods << TrackerMethod.new(obj, method_name)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
obj.send :extend, ObjectTracker.define_tracker_mod(obj, :TrackerExt, ObjectTracker.build_tracker_mod(class_methods, options))
|
61
|
+
if inst_methods.any?
|
62
|
+
obj.send :prepend, ObjectTracker.define_tracker_mod(obj, :InstanceTrackerExt, ObjectTracker.build_tracker_mod(inst_methods, options))
|
84
63
|
end
|
64
|
+
obj
|
85
65
|
end
|
86
66
|
|
87
|
-
def
|
88
|
-
|
89
|
-
|
90
|
-
end
|
67
|
+
def self.define_tracker_mod(context, name, mod)
|
68
|
+
context = context.class unless context.respond_to?(:const_set)
|
69
|
+
context.const_set name, mod
|
91
70
|
end
|
92
71
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
72
|
+
# @param trackers [Array<TrackerMethod>]
|
73
|
+
# @option :mod [Module] module to add tracking to, will be mixed into self
|
74
|
+
# @option :before [Proc] proc to call before method execution (e.g. ->(_name, _context, *_args) {})
|
75
|
+
# @option :after [Proc] proc to call after method execution (e.g. ->(_name, _context, *_args) {})
|
76
|
+
def self.build_tracker_mod(trackers, mod: Module.new, before: nil, after: nil)
|
77
|
+
ObjectTracker.tracker_hooks[:before] << before if before
|
78
|
+
ObjectTracker.tracker_hooks[:after] << after if after
|
79
|
+
Array(trackers).each do |tracker|
|
80
|
+
mod.module_eval <<-RUBY, __FILE__, __LINE__
|
81
|
+
def #{tracker.name}(*args)
|
82
|
+
ObjectTracker.call_tracker_hooks(:before, "#{tracker.display_name}", self, *args)
|
83
|
+
result, message = ObjectTracker.call_with_tracking("#{tracker.display_name}", args, "#{tracker.source}") { super }
|
84
|
+
puts message
|
85
|
+
result
|
86
|
+
ensure
|
87
|
+
ObjectTracker.call_tracker_hooks(:after, "#{tracker.display_name}", self, *args)
|
88
|
+
end
|
89
|
+
RUBY
|
104
90
|
end
|
105
|
-
|
91
|
+
mod
|
106
92
|
end
|
107
93
|
|
108
|
-
|
109
|
-
|
94
|
+
# @note If we don't rescue, watch out for segfaults o.0
|
95
|
+
def self.call_tracker_hooks(key, method_name, context, *args)
|
96
|
+
tracker_hooks[key].each do |hook|
|
97
|
+
hook.call(context, method_name, *args) rescue nil
|
98
|
+
end
|
110
99
|
end
|
111
100
|
|
112
|
-
def
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
101
|
+
def self.call_with_tracking(method_name, args, source)
|
102
|
+
result = nil
|
103
|
+
msg = %Q( * called "#{method_name}" )
|
104
|
+
msg << "with " << ObjectTracker.format_args(args) unless args.empty?
|
105
|
+
msg << "[#{source}]"
|
106
|
+
bm = Benchmark.measure do
|
107
|
+
result = yield rescue nil
|
117
108
|
end
|
109
|
+
[result, msg << " (%.5f)" % bm.real]
|
118
110
|
end
|
119
111
|
|
120
|
-
|
121
|
-
|
122
|
-
|
112
|
+
def self.format_args(args)
|
113
|
+
result = "["
|
114
|
+
args.each do |arg|
|
115
|
+
result << (arg ? arg.to_s : "nil")
|
116
|
+
result << ", "
|
123
117
|
end
|
118
|
+
result.sub! /,\s\z/, ""
|
119
|
+
result << "] "
|
124
120
|
end
|
125
121
|
|
126
|
-
|
127
|
-
|
128
|
-
ivars = instance_variables - [:@__tracking, :@__tracked_calls, :@__reserved_methods]
|
129
|
-
vars = ivars.map { |ivar| ivar.to_s + "=" + instance_variable_get(ivar).to_s }
|
130
|
-
%Q(#<#{self.class.name}:#{object_id}(tracking)#{' ' if vars.any? }#{vars.join(', ')}>)
|
131
|
-
end
|
122
|
+
def self.tracker_hooks
|
123
|
+
@__tracker_hooks ||= Hash.new { |me, key| me[key] = [] }
|
132
124
|
end
|
133
|
-
end
|
125
|
+
end
|
data/object_tracker.gemspec
CHANGED
@@ -8,12 +8,12 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = ObjectTracker::VERSION
|
9
9
|
spec.authors = ["Ryan Buckley"]
|
10
10
|
spec.email = ["arebuckley@gmail.com"]
|
11
|
-
spec.summary = %q{Track method calls to
|
12
|
-
spec.description = %q{Track method calls to
|
11
|
+
spec.summary = %q{Track method calls to any object.}
|
12
|
+
spec.description = %q{Track method calls to any object. Class and instance methods can be tracked (w/ arguments and source location).}
|
13
13
|
spec.homepage = 'https://github.com/ridiculous/object_tracker'
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
|
-
spec.files = `git ls-files
|
16
|
+
spec.files = `git ls-files`.split($/).keep_if { |f| f =~ /object_tracker/ and f !~ %r{test/} }
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: object_tracker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Buckley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,22 +38,16 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
-
description: Track method calls to
|
42
|
-
|
41
|
+
description: Track method calls to any object. Class and instance methods can be tracked
|
42
|
+
(w/ arguments and source location).
|
43
43
|
email:
|
44
44
|
- arebuckley@gmail.com
|
45
|
-
executables:
|
46
|
-
- console.rb
|
45
|
+
executables: []
|
47
46
|
extensions: []
|
48
47
|
extra_rdoc_files: []
|
49
48
|
files:
|
50
|
-
- ".gitignore"
|
51
|
-
- Gemfile
|
52
|
-
- LICENSE.txt
|
53
|
-
- README.md
|
54
|
-
- Rakefile
|
55
|
-
- bin/console.rb
|
56
49
|
- lib/object_tracker.rb
|
50
|
+
- lib/object_tracker/tracker_method.rb
|
57
51
|
- lib/object_tracker/version.rb
|
58
52
|
- object_tracker.gemspec
|
59
53
|
homepage: https://github.com/ridiculous/object_tracker
|
@@ -76,8 +70,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
70
|
version: '0'
|
77
71
|
requirements: []
|
78
72
|
rubyforge_project:
|
79
|
-
rubygems_version: 2.
|
73
|
+
rubygems_version: 2.6.8
|
80
74
|
signing_key:
|
81
75
|
specification_version: 4
|
82
|
-
summary: Track method calls to
|
76
|
+
summary: Track method calls to any object.
|
83
77
|
test_files: []
|
data/.gitignore
DELETED
data/Gemfile
DELETED
data/LICENSE.txt
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
Copyright (c) 2015 Ryan Buckley
|
2
|
-
|
3
|
-
MIT License
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
12
|
-
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
included in all copies or substantial portions of the Software.
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
DELETED
@@ -1,265 +0,0 @@
|
|
1
|
-
# Ruby ObjectTracker [](http://badge.fury.io/rb/object_tracker)
|
2
|
-
|
3
|
-
Track class and instance methods, including arguments and definition source. You can extend a class to track calls to itself and it's
|
4
|
-
instances, or extend instances directly. This can be helpful for debugging by providing info on what methods are being called on your object
|
5
|
-
|
6
|
-
## Requirements
|
7
|
-
|
8
|
-
* Ruby 2+
|
9
|
-
|
10
|
-
## Installation
|
11
|
-
|
12
|
-
Add this line to your application's Gemfile:
|
13
|
-
|
14
|
-
```ruby
|
15
|
-
gem 'object_tracker'
|
16
|
-
```
|
17
|
-
|
18
|
-
Or try it out by cloning the repo and running:
|
19
|
-
|
20
|
-
```bash
|
21
|
-
irb -I ./lib -r object_tracker
|
22
|
-
```
|
23
|
-
|
24
|
-
## Usage
|
25
|
-
|
26
|
-
```ruby
|
27
|
-
class MyKlass
|
28
|
-
extend ObjectTracker
|
29
|
-
|
30
|
-
def fetch(name)
|
31
|
-
"Fetch the ball, #{name}!"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
```
|
35
|
-
|
36
|
-
Track a single method:
|
37
|
-
|
38
|
-
```ruby
|
39
|
-
MyKlass.track :fetch
|
40
|
-
```
|
41
|
-
|
42
|
-
Or track all methods:
|
43
|
-
|
44
|
-
```ruby
|
45
|
-
MyKlass.track_all!
|
46
|
-
```
|
47
|
-
|
48
|
-
Or track an instance:
|
49
|
-
|
50
|
-
```ruby
|
51
|
-
obj = MyKlass.new.extend ObjectTracker
|
52
|
-
obj.track_all!
|
53
|
-
```
|
54
|
-
|
55
|
-
## Example
|
56
|
-
|
57
|
-
Tracking a Sequel::Model object:
|
58
|
-
|
59
|
-
```bash
|
60
|
-
>> Website.extend ObjectTracker
|
61
|
-
=> Website
|
62
|
-
>> Website.track_all!
|
63
|
-
* called "#inspect" [sequel-4.21.0/lib/sequel/model/base.rb:1368]
|
64
|
-
=> Website
|
65
|
-
>> Website.count
|
66
|
-
* called ".count" [sequel-4.21.0/lib/sequel/model/plugins.rb:28]
|
67
|
-
* called ".dataset" [sequel-4.21.0/lib/sequel/model/base.rb:157]
|
68
|
-
I, [2015-07-07T19:15:57.897695 #39091] INFO -- : (0.000794s) SELECT count(*) AS "count" FROM "websites" LIMIT 1
|
69
|
-
=> 0
|
70
|
-
>> Website.first
|
71
|
-
* called ".first" [sequel-4.21.0/lib/sequel/model/base.rb:459]
|
72
|
-
* called ".dataset" [sequel-4.21.0/lib/sequel/model/base.rb:157]
|
73
|
-
I, [2015-07-07T19:16:01.016948 #39091] INFO -- : (0.001045s) SELECT * FROM "websites" LIMIT 1
|
74
|
-
=> nil
|
75
|
-
>> Website.create(user_id: 101, url: 'http://cnn.com')
|
76
|
-
* called ".create" with {:user_id=>101, :url=>"http://cnn.com"} [sequel-4.21.0/lib/sequel/model/base.rb:147]
|
77
|
-
* called ".new" with {:user_id=>101, :url=>"http://cnn.com"} [RUBY CORE]
|
78
|
-
* called "#set" with {:user_id=>101, :url=>"http://cnn.com"} [sequel-4.21.0/lib/sequel/model/base.rb:1572]
|
79
|
-
* called ".setter_methods" with default [sequel-4.21.0/lib/sequel/model/base.rb:732]
|
80
|
-
* called "#model" [RUBY CORE]
|
81
|
-
* called ".setter_methods" [sequel-4.21.0/lib/sequel/model/base.rb:732]
|
82
|
-
* called ".allowed_columns" [sequel-4.21.0/lib/sequel/model/base.rb:13]
|
83
|
-
* called ".instance_methods" [RUBY CORE]
|
84
|
-
* called "#primary_key" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
85
|
-
* called ".restrict_primary_key?" [sequel-4.21.0/lib/sequel/model/base.rb:646]
|
86
|
-
* called "#primary_key" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
87
|
-
* called "#strict_param_setting" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
88
|
-
* called "#frozen?" [RUBY CORE]
|
89
|
-
* called "#strict_param_setting" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
90
|
-
* called "#set_column_value" with user_id=, 101 [RUBY CORE]
|
91
|
-
* called "#user_id=" with 101 [sequel-4.21.0/lib/sequel/model/base.rb:858]
|
92
|
-
* called "#typecast_on_assignment" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
93
|
-
* called "#frozen?" [RUBY CORE]
|
94
|
-
* called "#typecast_on_assignment" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
95
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
96
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
97
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
98
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
99
|
-
* called "#raise_on_typecast_failure" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
100
|
-
* called "#frozen?" [RUBY CORE]
|
101
|
-
* called "#raise_on_typecast_failure" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
102
|
-
* called "#model" [RUBY CORE]
|
103
|
-
* called "#db" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
104
|
-
* called "#new?" [sequel-4.21.0/lib/sequel/model/base.rb:1454]
|
105
|
-
* called "#model" [RUBY CORE]
|
106
|
-
* called ".autoreloading_associations" [sequel-4.21.0/lib/sequel/model/associations.rb:1417]
|
107
|
-
* called "#changed_columns" [sequel-4.21.0/lib/sequel/model/base.rb:1252]
|
108
|
-
* called "#set_column_value" with url=, http://cnn.com [RUBY CORE]
|
109
|
-
* called "#url=" with http://cnn.com [sequel-4.21.0/lib/sequel/model/base.rb:858]
|
110
|
-
* called "#typecast_on_assignment" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
111
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
112
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
113
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
114
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
115
|
-
* called "#raise_on_typecast_failure" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
116
|
-
* called "#model" [RUBY CORE]
|
117
|
-
* called "#db" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
118
|
-
* called "#new?" [sequel-4.21.0/lib/sequel/model/base.rb:1454]
|
119
|
-
* called "#model" [RUBY CORE]
|
120
|
-
* called ".autoreloading_associations" [sequel-4.21.0/lib/sequel/model/associations.rb:1417]
|
121
|
-
* called "#changed_columns" [sequel-4.21.0/lib/sequel/model/base.rb:1252]
|
122
|
-
* called "#changed_columns" [sequel-4.21.0/lib/sequel/model/base.rb:1252]
|
123
|
-
* called "#save" [sequel-4.21.0/lib/sequel/model/base.rb:1539]
|
124
|
-
* called "#frozen?" [RUBY CORE]
|
125
|
-
* called "#new?" [sequel-4.21.0/lib/sequel/model/base.rb:1454]
|
126
|
-
* called "#model" [RUBY CORE]
|
127
|
-
* called ".create_timestamp_field" [sequel-4.21.0/lib/sequel/plugins/timestamps.rb:40]
|
128
|
-
* called "#respond_to?" with created_at [RUBY CORE]
|
129
|
-
* called "#respond_to?" with created_at= [RUBY CORE]
|
130
|
-
* called "#model" [RUBY CORE]
|
131
|
-
* called ".create_timestamp_overwrite?" [sequel-4.21.0/lib/sequel/plugins/timestamps.rb:46]
|
132
|
-
* called "#get_column_value" with created_at [RUBY CORE]
|
133
|
-
* called "#created_at" [sequel-4.21.0/lib/sequel/model/base.rb:857]
|
134
|
-
* called "#model" [RUBY CORE]
|
135
|
-
* called ".dataset" [sequel-4.21.0/lib/sequel/model/base.rb:157]
|
136
|
-
* called "#set_column_value" with created_at=, 2015-07-07 19:16:24 -0700 [RUBY CORE]
|
137
|
-
* called "#created_at=" with 2015-07-07 19:16:24 -0700 [sequel-4.21.0/lib/sequel/model/base.rb:858]
|
138
|
-
* called "#typecast_on_assignment" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
139
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
140
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
141
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
142
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
143
|
-
* called "#raise_on_typecast_failure" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
144
|
-
* called "#model" [RUBY CORE]
|
145
|
-
* called "#db" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
146
|
-
* called "#new?" [sequel-4.21.0/lib/sequel/model/base.rb:1454]
|
147
|
-
* called "#model" [RUBY CORE]
|
148
|
-
* called ".autoreloading_associations" [sequel-4.21.0/lib/sequel/model/associations.rb:1417]
|
149
|
-
* called "#changed_columns" [sequel-4.21.0/lib/sequel/model/base.rb:1252]
|
150
|
-
* called "#model" [RUBY CORE]
|
151
|
-
* called ".set_update_timestamp_on_create?" [sequel-4.21.0/lib/sequel/plugins/timestamps.rb:54]
|
152
|
-
* called "#model" [RUBY CORE]
|
153
|
-
* called ".update_timestamp_field" [sequel-4.21.0/lib/sequel/plugins/timestamps.rb:43]
|
154
|
-
* called "#respond_to?" with updated_at= [RUBY CORE]
|
155
|
-
* called "#set_column_value" with updated_at=, 2015-07-07 19:16:24 -0700 [RUBY CORE]
|
156
|
-
* called "#updated_at=" with 2015-07-07 19:16:24 -0700 [sequel-4.21.0/lib/sequel/model/base.rb:858]
|
157
|
-
* called "#typecast_on_assignment" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
158
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
159
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
160
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
161
|
-
* called "#db_schema" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
162
|
-
* called "#raise_on_typecast_failure" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
163
|
-
* called "#model" [RUBY CORE]
|
164
|
-
* called "#db" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
165
|
-
* called "#new?" [sequel-4.21.0/lib/sequel/model/base.rb:1454]
|
166
|
-
* called "#model" [RUBY CORE]
|
167
|
-
* called ".autoreloading_associations" [sequel-4.21.0/lib/sequel/model/associations.rb:1417]
|
168
|
-
* called "#changed_columns" [sequel-4.21.0/lib/sequel/model/base.rb:1252]
|
169
|
-
* called "#raise_on_save_failure" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
170
|
-
* called "#frozen?" [RUBY CORE]
|
171
|
-
* called "#raise_on_save_failure" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
172
|
-
* called "#frozen?" [RUBY CORE]
|
173
|
-
* called "#errors" [sequel-4.21.0/lib/sequel/model/base.rb:1301]
|
174
|
-
* called "#around_validation" [sequel-4.21.0/lib/sequel/model/base.rb:1124]
|
175
|
-
* called "#before_validation" [sequel-4.21.0/lib/sequel/model/base.rb:1123]
|
176
|
-
* called "#validate" [apps/website-report-service/app/models/website_report.rb:7]
|
177
|
-
* called "#validates_presence" with user_id, url [sequel-4.21.0/lib/sequel/plugins/validation_helpers.rb:176]
|
178
|
-
* called "#get_column_value" with user_id [RUBY CORE]
|
179
|
-
* called "#user_id" [sequel-4.21.0/lib/sequel/model/base.rb:857]
|
180
|
-
* called "#model" [RUBY CORE]
|
181
|
-
* called "#db" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
182
|
-
* called "#get_column_value" with url [RUBY CORE]
|
183
|
-
* called "#url" [sequel-4.21.0/lib/sequel/model/base.rb:857]
|
184
|
-
* called "#model" [RUBY CORE]
|
185
|
-
* called "#db" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
186
|
-
* called "#after_validation" [sequel-4.21.0/lib/sequel/model/base.rb:1123]
|
187
|
-
* called "#errors" [sequel-4.21.0/lib/sequel/model/base.rb:1301]
|
188
|
-
* called "#errors" [sequel-4.21.0/lib/sequel/model/base.rb:1301]
|
189
|
-
* called "#raise_on_save_failure" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
190
|
-
* called "#use_transactions" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
191
|
-
* called "#frozen?" [RUBY CORE]
|
192
|
-
* called "#use_transactions" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
193
|
-
* called "#db" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
194
|
-
* called "#db" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
195
|
-
* called "#model" [RUBY CORE]
|
196
|
-
* called ".dataset" [sequel-4.21.0/lib/sequel/model/base.rb:157]
|
197
|
-
I, [2015-07-07T19:16:24.477282 #39091] INFO -- : (0.000231s) BEGIN
|
198
|
-
* called "#model" [RUBY CORE]
|
199
|
-
* called ".dataset" [sequel-4.21.0/lib/sequel/model/base.rb:157]
|
200
|
-
* called "#use_after_commit_rollback" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
201
|
-
* called "#frozen?" [RUBY CORE]
|
202
|
-
* called "#use_after_commit_rollback" [sequel-4.21.0/lib/sequel/model/base.rb:1135]
|
203
|
-
* called "#db" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
204
|
-
* called "#db" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
205
|
-
* called "#around_save" [sequel-4.21.0/lib/sequel/model/base.rb:1124]
|
206
|
-
* called "#before_save" [sequel-4.21.0/lib/sequel/model/base.rb:1123]
|
207
|
-
* called "#new?" [sequel-4.21.0/lib/sequel/model/base.rb:1454]
|
208
|
-
* called "#around_create" [sequel-4.21.0/lib/sequel/model/base.rb:1124]
|
209
|
-
* called "#before_create" [sequel-4.21.0/lib/sequel/model/base.rb:1123]
|
210
|
-
* called "#model" [RUBY CORE]
|
211
|
-
* called ".instance_dataset" [sequel-4.21.0/lib/sequel/model/base.rb:30]
|
212
|
-
I, [2015-07-07T19:16:24.479095 #39091] INFO -- : (0.001098s) INSERT INTO "websites" ("user_id", "url", "created_at", "updated_at") VALUES (101, 'http://cnn.com', '2015-07-07 19:16:24.476029-0700', '2015-07-07 19:16:24.476029-0700') RETURNING *
|
213
|
-
* called "#after_create" [sequel-4.21.0/lib/sequel/model/base.rb:1123]
|
214
|
-
* called "#after_save" [sequel-4.21.0/lib/sequel/model/base.rb:1123]
|
215
|
-
* called "#changed_columns" [sequel-4.21.0/lib/sequel/model/base.rb:1252]
|
216
|
-
* called "#db" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
217
|
-
* called "#db" [sequel-4.21.0/lib/sequel/model/base.rb:1130]
|
218
|
-
I, [2015-07-07T19:16:24.481081 #39091] INFO -- : (0.000411s) COMMIT
|
219
|
-
* called "#after_commit" [sequel-4.21.0/lib/sequel/model/base.rb:1123]
|
220
|
-
* called "#inspect" [sequel-4.21.0/lib/sequel/model/base.rb:1368]
|
221
|
-
* called "#model" [RUBY CORE]
|
222
|
-
* called ".name" [RUBY CORE]
|
223
|
-
```
|
224
|
-
|
225
|
-
141 method calls to create a new record with 2 columns!
|
226
|
-
|
227
|
-
|
228
|
-
## Troubleshooting
|
229
|
-
|
230
|
-
Having problems? Maybe a specific method is throwing some obscure error? Try ignoring that method, so we can get back on track!
|
231
|
-
|
232
|
-
```ruby
|
233
|
-
MyKlass.track_not :bad_method
|
234
|
-
MyKlass.track_all! #=> will exclude tracking for :bad_method
|
235
|
-
```
|
236
|
-
|
237
|
-
I've also noticed it doesn't work so well with namespaced classes in the format:
|
238
|
-
|
239
|
-
```ruby
|
240
|
-
class TopLevel::MyKlass
|
241
|
-
extend ObjectTracker
|
242
|
-
track_all!
|
243
|
-
end
|
244
|
-
```
|
245
|
-
|
246
|
-
If you encounter that problem, either extend the particular instance you're using, or if you can, rewrite it as:
|
247
|
-
|
248
|
-
```ruby
|
249
|
-
class TopLevel
|
250
|
-
class MyKlass
|
251
|
-
extend ObjectTracker
|
252
|
-
track_all!
|
253
|
-
end
|
254
|
-
end
|
255
|
-
```
|
256
|
-
## Issues
|
257
|
-
|
258
|
-
Doesn't work well (or at all) when trying to track Ruby core objects (`String`, `Array`, etc). You can work around this by
|
259
|
-
subclassing the target class before extending with `ObjectTracker`. For example:
|
260
|
-
|
261
|
-
```ruby
|
262
|
-
class MyArray < Array
|
263
|
-
extend ObjectTracker
|
264
|
-
end
|
265
|
-
```
|
data/Rakefile
DELETED
data/bin/console.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'bundler/setup'
|
4
|
-
require 'pp'
|
5
|
-
require 'object_tracker'
|
6
|
-
require 'irb'
|
7
|
-
|
8
|
-
class Wut
|
9
|
-
extend ObjectTracker
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
@data = []
|
13
|
-
@info = { name: 'foo', weight: 20 }
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_s
|
17
|
-
end
|
18
|
-
track_all!
|
19
|
-
end
|
20
|
-
|
21
|
-
IRB.start
|