object_tracker 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 38c819172d891939c51b5e14df92d15f8760ffc7
4
- data.tar.gz: dd482623f159888438a9c57680e8670b787797b8
3
+ metadata.gz: 5a7d0b65299e8afcbd85241099ca20179d143b74
4
+ data.tar.gz: 03425ae584ea22e6a94d928c9c566d42b3f2984d
5
5
  SHA512:
6
- metadata.gz: 3e9c235ef8a434f4130946d6d48c603d1b35e79e3a1ed1ed738259f9e679b62db6677fdf9fb74da7476b2ee176629e501d8c8b59de8d3dd0babc483050460611
7
- data.tar.gz: 9e665c361430a7d8002649a5da07478adbeb8f9ef729a7eb7f82f2ef33474172b680d1f70ee8f237624b25f1230dd36afb233c823dc50afa2fb3744bb66efb21
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
@@ -1,3 +1,3 @@
1
1
  module ObjectTracker
2
- VERSION = '1.2.0'.freeze
2
+ VERSION = '2.0.0'.freeze
3
3
  end
@@ -2,132 +2,124 @@ require 'benchmark'
2
2
  require 'object_tracker/version'
3
3
 
4
4
  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
5
+ autoload :TrackerMethod, 'object_tracker/tracker_method'
23
6
 
24
- def tracking?(method_name)
25
- tracking.keys.include?(cleanse(method_name).to_sym)
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
- def track_not(*args)
29
- args.each do |method_name|
30
- track_reserved_methods << method_name unless track_reserved_methods.include?(method_name)
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
- # PRIVATE
28
+ # Tracks method calls to the given object
44
29
  #
45
-
46
- def cleanse(str)
47
- str.to_s.sub(/^\w*[#.]/, '')
48
- end
49
-
50
- def track!(method_names = nil)
51
- mod = Module.new
52
- Array(method_names || tracking).each do |method_name, source_def|
53
- 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}"
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
- extend(Inspector)
83
- extend(mod)
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 track_methods_for(obj)
88
- (obj.methods - track_reserved_methods).each do |method_name|
89
- track_with_source(obj, method_name)
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
- 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
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
- tracking["#{name}#{prefix}#{method_name}".to_sym] = source.join(':').split('/').last(5).join('/')
91
+ mod
106
92
  end
107
93
 
108
- def tracking
109
- @__tracking ||= {}
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 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
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
- 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"
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
- 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
122
+ def self.tracker_hooks
123
+ @__tracker_hooks ||= Hash.new { |me, key| me[key] = [] }
132
124
  end
133
- end
125
+ end
@@ -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 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"]
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.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: 2016-02-17 00:00:00.000000000 Z
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 almost any object. Class and instance methods can
42
- be tracked (w/ arguments).
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.4.6
73
+ rubygems_version: 2.6.8
80
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