method_trace 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+