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.
- data/lib/method_trace.rb +184 -0
- metadata +67 -0
data/lib/method_trace.rb
ADDED
@@ -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
|
+
|