method_trace 0.0.1

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.
Files changed (2) hide show
  1. data/lib/method_trace.rb +184 -0
  2. metadata +67 -0
@@ -0,0 +1,184 @@
1
+ require 'rubygems'
2
+ require 'metafun'
3
+
4
+ module MethodTrace
5
+ module MethodDefinition
6
+ def self.definition_sites
7
+ @definition_sites ||= {}
8
+ end
9
+
10
+ module InstanceMethods
11
+ def method_added_with_method_definitions(method)
12
+ method_added_without_method_definitions(method)
13
+ name = "#{self.object_id}##{method}"
14
+ MethodTrace::MethodDefinition.definition_sites[name] = caller
15
+ end
16
+ end
17
+
18
+ def self.included(base)
19
+ base.send :include, InstanceMethods
20
+ base.instance_eval do
21
+ alias_method :method_added_without_method_definitions, :method_added
22
+ alias_method :method_added, :method_added_with_method_definitions
23
+ end
24
+ end
25
+
26
+ def self.extended(base)
27
+ base.extend InstanceMethods
28
+ class << base
29
+ alias_method :method_added_without_method_definitions, :method_added
30
+ alias_method :method_added, :method_added_with_method_definitions
31
+ end
32
+ end
33
+ end
34
+
35
+ module SingletonMethodDefinition
36
+ module InstanceMethods
37
+ def singleton_method_added_with_method_definitions(method)
38
+ singleton_method_added_without_method_definitions(method)
39
+ name = "#{self.object_id}::#{method}"
40
+ MethodTrace::MethodDefinition.definition_sites[name] = caller
41
+ end
42
+ end
43
+
44
+ def self.included(base)
45
+ base.send :include, InstanceMethods
46
+ base.instance_eval do
47
+ alias_method :singleton_method_added_without_method_definitions, :singleton_method_added
48
+ alias_method :singleton_method_added, :singleton_method_added_with_method_definitions
49
+ end
50
+ end
51
+ end
52
+
53
+ module MethodAdditions
54
+ def self.included(base)
55
+ base.send :include, InstanceMethods
56
+ base.send :attr_accessor, :source, :name
57
+ end
58
+
59
+ module InstanceMethods
60
+ def backtrace
61
+ definition
62
+ end
63
+
64
+ def site
65
+ backtrace.find { |x| x !~ /method_added/ } || "filtered:filtered"
66
+ end
67
+
68
+ def file
69
+ @file ||= site.split(':')[0]
70
+ end
71
+
72
+ def line
73
+ @line ||= site.split(':')[1]
74
+ end
75
+
76
+ def from
77
+ definition
78
+ @from
79
+ end
80
+ end
81
+ end
82
+
83
+ module ObjectAdditions
84
+ def self.included(base)
85
+ base.send :include, InstanceMethods
86
+
87
+ base.send :alias_method, :method_without_method_definitions, :method
88
+ base.send :alias_method, :method, :method_with_method_definitions
89
+ end
90
+
91
+ module InstanceMethods
92
+ def method_with_method_definitions(name)
93
+ result = method_without_method_definitions(name)
94
+ result.source = self
95
+ result.name = name
96
+ result
97
+ end
98
+ end
99
+ end
100
+
101
+ module ClassAdditions
102
+ def self.included(base)
103
+ base.send :include, InstanceMethods
104
+
105
+ base.send :alias_method, :instance_method_without_method_definitions, :instance_method
106
+ base.send :alias_method, :instance_method, :instance_method_with_method_definitions
107
+ end
108
+
109
+ module InstanceMethods
110
+ def instance_method_with_method_definitions(name)
111
+ result = instance_method_without_method_definitions(name)
112
+ result.source = self
113
+ result.name = name
114
+ result
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ class Method
121
+ include MethodTrace::MethodAdditions
122
+
123
+ def definition
124
+ @definition ||= begin
125
+ if source.is_a?(Class)
126
+ # if class: base class singleton methods
127
+ source.class_hierarchy.each do |cls|
128
+ d = MethodTrace::MethodDefinition.definition_sites["#{cls.object_id}::#{self.name}"]
129
+ @from = cls and return d if d
130
+ end
131
+ else
132
+ # singleton methods
133
+ d = MethodTrace::MethodDefinition.definition_sites["#{source.object_id}::#{self.name}"]
134
+ @from = 'singleton' and return d if d
135
+ end
136
+
137
+ # base class methods
138
+ source.class.class_hierarchy.each do |cls|
139
+ d = MethodTrace::MethodDefinition.definition_sites["#{cls.object_id}##{self.name}"]
140
+ @from = cls and return d if d
141
+ end
142
+
143
+ # module methods
144
+ source.usable_modules.each do |mod|
145
+ d = MethodTrace::MethodDefinition.definition_sites["#{mod.object_id}##{self.name}"]
146
+ @from = mod and return d if d
147
+ end
148
+
149
+ ['unknown']
150
+ end
151
+ end
152
+ end
153
+
154
+ class UnboundMethod
155
+ include MethodTrace::MethodAdditions
156
+
157
+ def definition
158
+ @definition ||= begin
159
+ source.ancestors.each do |ancestor|
160
+ d = MethodTrace::MethodDefinition.definition_sites["#{ancestor.object_id}##{self.name}"]
161
+ @from = ancestor and return d if d
162
+ end
163
+
164
+ ['unknown']
165
+ end
166
+ end
167
+ end
168
+
169
+ class Module
170
+ include MethodTrace::MethodDefinition
171
+ end
172
+
173
+ class Object
174
+ extend MethodTrace::MethodDefinition
175
+ include MethodTrace::SingletonMethodDefinition
176
+ end
177
+
178
+ class Object
179
+ include MethodTrace::ObjectAdditions
180
+ end
181
+
182
+ class Class
183
+ include MethodTrace::ClassAdditions
184
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: method_trace
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Thomas Kadauke
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-01-29 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description:
23
+ email: thomas.kadauke@googlemail.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - lib/method_trace.rb
32
+ has_rdoc: true
33
+ homepage: http://github.com/tkadauke/method_trace
34
+ licenses: []
35
+
36
+ post_install_message:
37
+ rdoc_options: []
38
+
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ hash: 3
47
+ segments:
48
+ - 0
49
+ version: "0"
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ hash: 3
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.3.7
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Find method definition site
66
+ test_files: []
67
+