object_tracker 1.2.0 → 2.1.2

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
- SHA1:
3
- metadata.gz: 38c819172d891939c51b5e14df92d15f8760ffc7
4
- data.tar.gz: dd482623f159888438a9c57680e8670b787797b8
2
+ SHA256:
3
+ metadata.gz: 63c59cce7d3bba4a5232628842efe85ed40f7a50d7f5c7cc9c453594168ffed9
4
+ data.tar.gz: c808d787b3cde1fde5bf08b8935adb9c7d410f2edbf23d6b0981cb6dcd5ae0c6
5
5
  SHA512:
6
- metadata.gz: 3e9c235ef8a434f4130946d6d48c603d1b35e79e3a1ed1ed738259f9e679b62db6677fdf9fb74da7476b2ee176629e501d8c8b59de8d3dd0babc483050460611
7
- data.tar.gz: 9e665c361430a7d8002649a5da07478adbeb8f9ef729a7eb7f82f2ef33474172b680d1f70ee8f237624b25f1230dd36afb233c823dc50afa2fb3744bb66efb21
6
+ metadata.gz: 300b9a31ea415e2b20943cd82741cd81d93c436b92ce2d5debae6568051f2fc1a47c85fc9bc6acd6a7a6fd65d3533ea7b0ddf0029a09b637a81fb40d6978376c
7
+ data.tar.gz: 938f67a6a695766796e3be8c90c3ef4f2cbbabdfe3714fbe248f8ee0f2c0996f9e3c51f68c2d8834166dbc938ceeaea4be09913367ec3da5c5e0d474c156d053
@@ -1,133 +1,165 @@
1
+ require 'logger'
1
2
  require 'benchmark'
2
3
  require 'object_tracker/version'
3
4
 
4
5
  module ObjectTracker
5
- def track(*args)
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
6
+ autoload :TrackerMethod, 'object_tracker/tracker_method'
7
+ autoload :LogFormatter, 'object_tracker/log_formatter'
23
8
 
24
- def tracking?(method_name)
25
- tracking.keys.include?(cleanse(method_name).to_sym)
9
+ # @param method_names [Array<Symbol>] method names to track
10
+ # @option :except [Array<Symbol>] method names to NOT track
11
+ # @option :before [Proc] proc to call before method execution (e.g. ->(name, context, args) {})
12
+ # @option :after [Proc] proc to call after method execution (e.g. ->(name, context, args, duration) {})
13
+ def track_all!(method_names = [], **options)
14
+ ObjectTracker.(self, method_names, **options)
15
+ self
26
16
  end
27
17
 
28
- def track_not(*args)
29
- args.each do |method_name|
30
- track_reserved_methods << method_name unless track_reserved_methods.include?(method_name)
18
+ class << self
19
+ attr_writer :logger
20
+
21
+ def logger
22
+ @logger ||= Logger.new(STDOUT).tap do |config|
23
+ config.formatter = LogFormatter.new
24
+ end
31
25
  end
32
- nil
33
- end
34
26
 
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!
27
+ def reserved_tracker_methods
28
+ @__reserved_methods ||= begin
29
+ names = [:__send__]
30
+ names.concat [:default_scope, :current_scope=] if defined?(Rails)
31
+ names
32
+ end
33
+ end
40
34
  end
41
35
 
36
+ #= Utilities (not extended or mixed in)
42
37
  #
43
- # PRIVATE
38
+ # Tracks method calls to the given object
44
39
  #
40
+ # @note Alias to .()
41
+ #
42
+ # @param obj [Object] class or instance to track
43
+ # @param method_names [Array<Symbol>] method names to track
44
+ # @option :except [Array<Symbol>] method names to NOT track
45
+ # @option :before [Proc] proc to call before method execution (e.g. ->(name, context, args) {})
46
+ # @option :after [Proc] proc to call after method execution (e.g. ->(name, context, args, duration) {})
47
+ def self.call(obj, method_names = [], except: [], **options)
48
+ class_methods, inst_methods = ObjectTracker.build_tracker_methods(obj, method_names, except: except)
49
+ name = obj.to_s
50
+ obj.send :extend, ObjectTracker.define_tracker_mod(obj, :TrackerExt, ObjectTracker.build_tracker_mod(class_methods, **options))
51
+ if inst_methods.any?
52
+ # Silence all the noise about comparing class name and checking object behavior
53
+ ObjectTracker.with_error_logging do
54
+ obj.send :prepend, ObjectTracker.define_tracker_mod(obj, :InstanceTrackerExt, ObjectTracker.build_tracker_mod(inst_methods, **options))
55
+ end
56
+ end
57
+ logger.info { "following #{name}" }
58
+ obj
59
+ end
45
60
 
46
- def cleanse(str)
47
- str.to_s.sub(/^\w*[#.]/, '')
61
+ def self.define_tracker_mod(context, name, mod)
62
+ context = context.class unless context.respond_to?(:const_set)
63
+ if context.const_defined?(name, false)
64
+ context.send :remove_const, name
65
+ end
66
+ context.const_set name, mod
48
67
  end
49
68
 
50
- def track!(method_names = nil)
51
- mod = Module.new
52
- Array(method_names || tracking).each do |method_name, source_def|
69
+ # @param trackers [Array<TrackerMethod>]
70
+ # @option :mod [Module] module to add tracking to, will be mixed into self
71
+ # @option :before [Proc] proc to call before method execution (e.g. ->(name, context, args) {})
72
+ # @option :after [Proc] proc to call after method execution (e.g. ->(name, context, args, duration) {})
73
+ def self.build_tracker_mod(trackers, mod: Module.new, before: nil, after: nil)
74
+ ObjectTracker.tracker_hooks[:before] << before if before
75
+ ObjectTracker.tracker_hooks[:after] << after if after
76
+ Array(trackers).each do |tracker|
53
77
  mod.module_eval <<-RUBY, __FILE__, __LINE__
54
- def #{cleanse(method_name)}(*args)
55
- msg = %Q( * called "#{method_name}" )
56
- msg << "with " << args.join(', ') << " " if args.any?
57
- msg << "[#{source_def}]"
58
- result = nil
59
- bm = Benchmark.measure { result = super }
60
- msg << " (%.5f)" % bm.real
61
- puts msg
62
- @__tracked_calls ||= Set.new
63
- @__tracked_calls << "#{method_name}"
78
+ def #{tracker.name}(*args)
79
+ ObjectTracker.call_tracker_hooks(:before, "#{tracker.display_name}", self, args)
80
+ result, message, duration = ObjectTracker.call_with_tracking("#{tracker.display_name}", args, "#{tracker.source}") { super }
81
+ ObjectTracker.logger.debug { message + " (%.5f)" % duration }
64
82
  result
65
- rescue NoMethodError => e
66
- raise e if e.message !~ /no superclass/
83
+ ensure
84
+ ObjectTracker.call_tracker_hooks(:after, "#{tracker.display_name}", self, args, duration)
67
85
  end
68
86
  RUBY
69
87
  end
88
+ mod
89
+ end
70
90
 
71
- mod.module_eval <<-RUBY, __FILE__, __LINE__
72
- def self.prepended(base)
73
- base.extend(self)
74
- end
75
- RUBY
91
+ #
92
+ # Private
93
+ #
76
94
 
77
- # Handle both instance and class level extension
78
- if Class === self
79
- prepend(Inspector)
80
- prepend(mod)
95
+ def self.build_tracker_methods(obj, method_names, except: [])
96
+ class_methods, inst_methods = [], []
97
+ reserved = obj.respond_to?(:reserved_tracker_methods) ? obj.reserved_tracker_methods : ObjectTracker.reserved_tracker_methods
98
+ obj_instance = obj.respond_to?(:allocate) ? obj.allocate : obj
99
+ if Array(method_names).any?
100
+ Array(method_names).each do |method_name|
101
+ if obj.methods.include?(method_name)
102
+ class_methods << TrackerMethod.new(obj, method_name)
103
+ elsif obj.respond_to?(:instance_method)
104
+ inst_methods << TrackerMethod.new(obj_instance, method_name)
105
+ end
106
+ end
81
107
  else
82
- extend(Inspector)
83
- extend(mod)
108
+ if obj.respond_to?(:instance_methods)
109
+ (obj.instance_methods - reserved - Array(except)).each do |method_name|
110
+ inst_methods << TrackerMethod.new(obj_instance, method_name)
111
+ end
112
+ end
113
+ (obj.methods - reserved - Array(except)).each do |method_name|
114
+ class_methods << TrackerMethod.new(obj, method_name)
115
+ end
84
116
  end
117
+ return class_methods, inst_methods
85
118
  end
86
119
 
87
- def track_methods_for(obj)
88
- (obj.methods - track_reserved_methods).each do |method_name|
89
- track_with_source(obj, method_name)
120
+ # @note If we don't rescue, watch out for segfaults o.0
121
+ def self.call_tracker_hooks(key, method_name, context, args, duration = nil)
122
+ tracker_hooks[key].each do |hook|
123
+ begin
124
+ if duration
125
+ hook.call(context, method_name, args, duration)
126
+ else
127
+ hook.call(context, method_name, args)
128
+ end
129
+ rescue Exception
130
+ next
131
+ end
90
132
  end
91
133
  end
92
134
 
93
- def track_with_source(obj, method_name)
94
- source = obj.method(method_name).source_location || ['RUBY CORE']
95
- if Class === obj || Module === obj
96
- name = obj.name
97
- prefix = '.'
98
- elsif obj.class === Class
99
- prefix = '.'
100
- name = obj.class.name
101
- else
102
- prefix = '#'
103
- name = obj.class.name
135
+ def self.call_with_tracking(msg, args, source)
136
+ result = nil
137
+ msg += ObjectTracker.format_args(args) unless args.empty?
138
+ msg += " [#{source}]"
139
+ bm = Benchmark.measure do
140
+ result = yield rescue nil
104
141
  end
105
- tracking["#{name}#{prefix}#{method_name}".to_sym] = source.join(':').split('/').last(5).join('/')
142
+ [result, msg, bm.real]
106
143
  end
107
144
 
108
- def tracking
109
- @__tracking ||= {}
110
- end
111
-
112
- def track_reserved_methods
113
- @__reserved_methods ||= begin
114
- names = [:__send__, :object_id]
115
- names.concat [:default_scope, :base_class, :superclass, :<, :current_scope=] if defined?(Rails)
116
- names
145
+ def self.format_args(args)
146
+ result = " with ["
147
+ args.each do |arg|
148
+ result << (arg ? arg.to_s : "nil")
149
+ result << ", "
117
150
  end
151
+ result.sub! /,\s\z/, ""
152
+ result << "]"
118
153
  end
119
154
 
120
- class UntrackableMethod < StandardError
121
- def initialize(method_name)
122
- super "Can't track :#{method_name} because it's not defined on this class or it's instance"
123
- end
155
+ def self.tracker_hooks
156
+ @__tracker_hooks ||= Hash.new { |me, key| me[key] = [] }
124
157
  end
125
158
 
126
- module Inspector
127
- def inspect
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
159
+ def self.with_error_logging
160
+ old_log_level, logger.level = logger.level, Logger::ERROR
161
+ yield
162
+ ensure
163
+ logger.level = old_log_level if old_log_level
132
164
  end
133
- end
165
+ end
@@ -0,0 +1,10 @@
1
+ module ObjectTracker
2
+ class LogFormatter < Logger::Formatter
3
+ FORMAT = "[%s] %5s -- ObjectTracker: %s\n".freeze
4
+ TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%6N".freeze
5
+
6
+ def call(severity, time, _progname, msg)
7
+ FORMAT % [time.strftime(TIME_FORMAT), severity, msg2str(msg)]
8
+ end
9
+ end
10
+ end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module ObjectTracker
2
- VERSION = '1.2.0'.freeze
2
+ VERSION = '2.1.2'.freeze
3
3
  end
@@ -8,18 +8,18 @@ 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 almost any object.}
12
- spec.description = %q{Track method calls to almost any object. Class and instance methods can be tracked (w/ arguments).}
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 -z`.split("\x0")
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"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.10"
22
- spec.add_development_dependency "rake", "~> 10.0"
21
+ spec.add_development_dependency "bundler", "~> 2.2.11"
22
+ spec.add_development_dependency "rake", ">= 12.3.3"
23
23
 
24
24
  spec.required_ruby_version = '>= 2.0.0'
25
25
  end
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: 1.2.0
4
+ version: 2.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Buckley
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-17 00:00:00.000000000 Z
11
+ date: 2021-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,51 +16,46 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.10'
19
+ version: 2.2.11
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.10'
26
+ version: 2.2.11
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 12.3.3
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
41
- description: Track method calls to almost any object. Class and instance methods can
42
- be tracked (w/ arguments).
40
+ version: 12.3.3
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/log_formatter.rb
51
+ - lib/object_tracker/tracker_method.rb
57
52
  - lib/object_tracker/version.rb
58
53
  - object_tracker.gemspec
59
54
  homepage: https://github.com/ridiculous/object_tracker
60
55
  licenses:
61
56
  - MIT
62
57
  metadata: {}
63
- post_install_message:
58
+ post_install_message:
64
59
  rdoc_options: []
65
60
  require_paths:
66
61
  - lib
@@ -75,9 +70,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
70
  - !ruby/object:Gem::Version
76
71
  version: '0'
77
72
  requirements: []
78
- rubyforge_project:
79
- rubygems_version: 2.4.6
80
- signing_key:
73
+ rubygems_version: 3.2.11
74
+ signing_key:
81
75
  specification_version: 4
82
- summary: Track method calls to almost any object.
76
+ summary: Track method calls to any object.
83
77
  test_files: []
data/.gitignore DELETED
@@ -1,15 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- *.bundle
11
- *.so
12
- *.o
13
- *.a
14
- mkmf.log
15
- *.gem
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in object_tracker.gemspec
4
- gemspec
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 [![Gem Version](https://badge.fury.io/rb/object_tracker.svg)](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
@@ -1,2 +0,0 @@
1
- require "bundler/gem_tasks"
2
-
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