drx 0.0.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/{lib → examples}/drx_test.rb +3 -4
- data/{lib → examples}/drx_test2.rb +12 -7
- data/examples/drx_test3.rb +35 -0
- data/ext/{drx_ext.c → drx_core.c} +76 -45
- data/ext/extconf.rb +1 -1
- data/lib/drx/graphviz.rb +240 -0
- data/lib/drx/objinfo.rb +147 -0
- data/lib/drx/tempfiles.rb +44 -0
- data/lib/drx/tk/app.rb +363 -0
- data/lib/drx/tk/imagemap.rb +284 -0
- data/lib/drx.rb +21 -56
- metadata +16 -9
- data/lib/drxtk.rb +0 -210
data/lib/drx.rb
CHANGED
@@ -1,67 +1,32 @@
|
|
1
|
-
|
1
|
+
# Bootstraps the library and defines some utility functions for the end-user.
|
2
2
|
|
3
|
-
|
3
|
+
require 'drx_core' # The C extension.
|
4
|
+
require 'drx/objinfo'
|
5
|
+
require 'drx/graphviz'
|
4
6
|
|
5
7
|
module Drx
|
6
8
|
|
7
|
-
def self.
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
else
|
13
|
-
return obj.inspect + (is_singleton ? " 'S" : "")
|
14
|
-
end
|
9
|
+
def self.see_using_tk(obj)
|
10
|
+
require 'drx/tk/app'
|
11
|
+
app = Drx::TkGUI::Application.new
|
12
|
+
app.see(obj)
|
13
|
+
app.run
|
15
14
|
end
|
16
15
|
|
17
|
-
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
address = Drx.get_address(obj)
|
26
|
-
seen = $seen[address]
|
27
|
-
$seen[address] = true
|
28
|
-
|
29
|
-
if seen
|
30
|
-
line += " [seen]" # #{address.to_s}"
|
31
|
-
end
|
32
|
-
|
33
|
-
if block_given?
|
34
|
-
yield line, obj
|
35
|
-
else
|
36
|
-
puts line
|
37
|
-
end
|
38
|
-
|
39
|
-
return if seen
|
40
|
-
|
41
|
-
if Drx.is_class_like(obj)
|
42
|
-
# Kernel has a NULL super.
|
43
|
-
# Modules too have NULL super, unless when 'include'ing.
|
44
|
-
if Drx.get_super(obj) # Warning: we can't do 'if !Drx.get_super(obj).#nil?' because
|
45
|
-
# T_ICLASS doesn't "have" #nil.
|
46
|
-
Drx.examine(Drx.get_super(obj), level+1, '[super]', &block)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# Dipslaying a T_ICLASS's klass isn't very useful, because the data
|
51
|
-
# is already mirrored in the m_tbl and iv_tvl of the T_ICLASS itself.
|
52
|
-
if Drx.get_type(obj) != Drx::T_ICLASS
|
53
|
-
Drx.examine(Drx.get_klass(obj), level+1, '[klass]', &block)
|
54
|
-
end
|
16
|
+
class << self
|
17
|
+
# DrX::see() launches the GUI for inspecting an object. It is perhaps the only
|
18
|
+
# function the end-user is going to know about. It can also be invoked via
|
19
|
+
# Object#see().
|
20
|
+
#
|
21
|
+
# my_obj = "foobar"
|
22
|
+
# my_object.see
|
23
|
+
alias :see :see_using_tk
|
55
24
|
end
|
56
25
|
|
57
|
-
|
58
|
-
Drx.get_type(obj) == T_OBJECT or Drx.is_class_like(obj)
|
59
|
-
end
|
26
|
+
end
|
60
27
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
[Drx::T_CLASS, Drx::T_ICLASS, Drx::T_MODULE].include? Drx.get_type(obj)
|
28
|
+
class Object
|
29
|
+
def see
|
30
|
+
Drx.see(self)
|
65
31
|
end
|
66
|
-
|
67
32
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: drx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mooffie
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-03-28 00:00:00 +03:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -23,14 +23,21 @@ extra_rdoc_files: []
|
|
23
23
|
|
24
24
|
files:
|
25
25
|
- README
|
26
|
-
- lib/
|
27
|
-
- lib/
|
28
|
-
- lib/
|
26
|
+
- lib/drx/graphviz.rb
|
27
|
+
- lib/drx/tk/imagemap.rb
|
28
|
+
- lib/drx/tk/app.rb
|
29
|
+
- lib/drx/objinfo.rb
|
30
|
+
- lib/drx/tempfiles.rb
|
29
31
|
- lib/drx.rb
|
30
32
|
- ext/extconf.rb
|
31
|
-
- ext/
|
32
|
-
|
33
|
+
- ext/drx_core.c
|
34
|
+
- examples/drx_test.rb
|
35
|
+
- examples/drx_test3.rb
|
36
|
+
- examples/drx_test2.rb
|
37
|
+
has_rdoc: true
|
33
38
|
homepage: http://drx.rubyforge.org/
|
39
|
+
licenses: []
|
40
|
+
|
34
41
|
post_install_message:
|
35
42
|
rdoc_options: []
|
36
43
|
|
@@ -51,9 +58,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
58
|
requirements: []
|
52
59
|
|
53
60
|
rubyforge_project: drx
|
54
|
-
rubygems_version: 1.3.
|
61
|
+
rubygems_version: 1.3.5
|
55
62
|
signing_key:
|
56
|
-
specification_version:
|
63
|
+
specification_version: 3
|
57
64
|
summary: Inspect Ruby objects.
|
58
65
|
test_files: []
|
59
66
|
|
data/lib/drxtk.rb
DELETED
@@ -1,210 +0,0 @@
|
|
1
|
-
require 'drx'
|
2
|
-
require 'tk'
|
3
|
-
|
4
|
-
module Drx
|
5
|
-
def self.examinetk(obj)
|
6
|
-
app = Drx::TkGUI::DrxWindow.new
|
7
|
-
app.see(obj)
|
8
|
-
app.run
|
9
|
-
end
|
10
|
-
|
11
|
-
# easier to type...
|
12
|
-
def self.see(obj)
|
13
|
-
examinetk(obj)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
module Drx
|
18
|
-
module TkGUI
|
19
|
-
|
20
|
-
# The 'DRX_EDITOR_COMMAND' environment variable overrides this.
|
21
|
-
EDITOR_COMMAND = 'gedit +%d "%s"'
|
22
|
-
|
23
|
-
class ScrolledListbox < TkFrame
|
24
|
-
def initialize(*args, &block)
|
25
|
-
super(*args, &block)
|
26
|
-
@the_list = the_list = TkListbox.new(self) {
|
27
|
-
#pack :side => 'left'#, :expand => 'true', :fill => 'both'
|
28
|
-
}
|
29
|
-
TkScrollbar.new(self) { |s|
|
30
|
-
pack :side => 'right', :fill => 'y'
|
31
|
-
command { |*args| the_list.yview *args }
|
32
|
-
the_list.yscrollcommand { |first,last| s.set first,last }
|
33
|
-
}
|
34
|
-
TkScrollbar.new(self) { |s|
|
35
|
-
orient 'horizontal'
|
36
|
-
pack :side => 'bottom', :fill => 'x'
|
37
|
-
command { |*args| the_list.xview *args }
|
38
|
-
the_list.xscrollcommand { |first,last| s.set first,last }
|
39
|
-
}
|
40
|
-
@the_list.pack(:side => 'left', :expand => 'true', :fill => 'both')
|
41
|
-
end
|
42
|
-
def the_list
|
43
|
-
@the_list
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
class ::TkListbox
|
48
|
-
def get_selection
|
49
|
-
idx = curselection[0]
|
50
|
-
return get(idx)
|
51
|
-
end
|
52
|
-
def get_index
|
53
|
-
curselection[0]
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
class DrxWindow
|
58
|
-
def initialize
|
59
|
-
@stack = []
|
60
|
-
root = TkRoot.new
|
61
|
-
@evalbox = TkEntry.new(root) {
|
62
|
-
font 'Courier'
|
63
|
-
pack(:side => 'bottom', :fill => 'both')
|
64
|
-
}
|
65
|
-
TkLabel.new(root, :anchor => 'w') {
|
66
|
-
text 'Type some code to eval in the context of the selected object; prepend with "see" to examine it.'
|
67
|
-
pack(:side => 'bottom', :fill => 'both')
|
68
|
-
}
|
69
|
-
@list = (ScrolledListbox.new(root) {
|
70
|
-
pack :side => 'left', :fill => 'both', :expand => true
|
71
|
-
}).the_list
|
72
|
-
@list.width 52
|
73
|
-
@list.height 25
|
74
|
-
@list.focus
|
75
|
-
@varsbox = (ScrolledListbox.new(root) {
|
76
|
-
pack :side => 'left', :fill => 'both', :expand => true
|
77
|
-
}).the_list
|
78
|
-
@methodsbox = (ScrolledListbox.new(root) {
|
79
|
-
pack :side => 'left', :fill => 'both', :expand => true
|
80
|
-
}).the_list
|
81
|
-
|
82
|
-
@list.bind('<ListboxSelect>') {
|
83
|
-
@current_object = @objs[@list.get_index]
|
84
|
-
display_variables(current_object)
|
85
|
-
display_methods(current_object)
|
86
|
-
}
|
87
|
-
@list.bind('ButtonRelease-3') {
|
88
|
-
back
|
89
|
-
}
|
90
|
-
@list.bind('Double-Button-1') {
|
91
|
-
descend_iclass
|
92
|
-
}
|
93
|
-
@varsbox.bind('<ListboxSelect>') {
|
94
|
-
print "\n== Variable #{@varsbox.get_selection}\n\n"
|
95
|
-
p selected_var
|
96
|
-
}
|
97
|
-
@varsbox.bind('Double-Button-1') {
|
98
|
-
see selected_var
|
99
|
-
}
|
100
|
-
@varsbox.bind('ButtonRelease-3') {
|
101
|
-
require 'pp'
|
102
|
-
print "\n== Variable #{@varsbox.get_selection}\n\n"
|
103
|
-
pp selected_var
|
104
|
-
}
|
105
|
-
@evalbox.bind('Key-Return') {
|
106
|
-
eval_code
|
107
|
-
}
|
108
|
-
@methodsbox.bind('Double-Button-1') {
|
109
|
-
locate_method(current_object, @methodsbox.get_selection)
|
110
|
-
}
|
111
|
-
end
|
112
|
-
|
113
|
-
def open_up_editor(filename, lineno)
|
114
|
-
command = sprintf(ENV['DRX_EDITOR_COMMAND'] || EDITOR_COMMAND, lineno, filename)
|
115
|
-
puts "Execting: #{command}..."
|
116
|
-
if !fork
|
117
|
-
if !Kernel.system(command)
|
118
|
-
puts "Could not execure the command '#{command}'"
|
119
|
-
end
|
120
|
-
exit!
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
def locate_method(obj, method_name)
|
125
|
-
place = Drx.locate_method(obj, method_name)
|
126
|
-
if !place
|
127
|
-
puts "Method #{method_name} doesn't exist"
|
128
|
-
else
|
129
|
-
if place =~ /\A(\d+):(.*)/
|
130
|
-
open_up_editor($2, $1)
|
131
|
-
else
|
132
|
-
puts "Can't locate method, because: #{place}"
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def back
|
138
|
-
if @stack.size > 1
|
139
|
-
@stack.pop
|
140
|
-
see @stack.pop
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
def selected_var
|
145
|
-
Drx.get_ivar(current_object, @varsbox.get_selection)
|
146
|
-
end
|
147
|
-
|
148
|
-
def eval_code
|
149
|
-
code = @evalbox.get.strip
|
150
|
-
see = !!code.sub!(/^see\s/, '')
|
151
|
-
result = current_object.instance_eval(code)
|
152
|
-
p result
|
153
|
-
see(result) if see
|
154
|
-
end
|
155
|
-
|
156
|
-
def current_object
|
157
|
-
@current_object
|
158
|
-
end
|
159
|
-
|
160
|
-
def display_variables(obj)
|
161
|
-
@varsbox.delete('0', 'end')
|
162
|
-
if (Drx.has_iv_tbl(obj))
|
163
|
-
vars = Drx.get_iv_tbl(obj).keys.map do |v| v.to_s end.sort
|
164
|
-
# Get rid of gazillions of Tk classes:
|
165
|
-
vars = vars.reject { |v| v =~ /Tk|Ttk/ }
|
166
|
-
@varsbox.insert('end', *vars)
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
def display_methods(obj)
|
171
|
-
@methodsbox.delete('0', 'end')
|
172
|
-
if (Drx.is_class_like(obj))
|
173
|
-
methods = Drx.get_m_tbl(obj).keys.map do |v| v.to_s end.sort
|
174
|
-
@methodsbox.insert('end', *methods)
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
def display_hierarchy(obj)
|
179
|
-
@list.delete('0', 'end')
|
180
|
-
@objs = []
|
181
|
-
Drx.examine(obj) do |line, o|
|
182
|
-
@list.insert('end', line)
|
183
|
-
@objs << o
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
def see(obj)
|
188
|
-
@current_object = obj
|
189
|
-
@stack << obj
|
190
|
-
display_hierarchy(obj)
|
191
|
-
display_variables(obj)
|
192
|
-
display_methods(obj)
|
193
|
-
end
|
194
|
-
|
195
|
-
def descend_iclass
|
196
|
-
obj = if Drx.get_type(current_object) == Drx::T_ICLASS
|
197
|
-
Drx.get_klass(current_object)
|
198
|
-
else
|
199
|
-
current_object
|
200
|
-
end
|
201
|
-
see(obj)
|
202
|
-
end
|
203
|
-
|
204
|
-
def run
|
205
|
-
Tk.mainloop
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
end # module TkGUI
|
210
|
-
end # module Drx
|