drx 0.0.1 → 0.0.2

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 (4) hide show
  1. data/ext/drx_ext.c +102 -5
  2. data/lib/drx_test.rb +1 -2
  3. data/lib/drxtk.rb +101 -17
  4. metadata +2 -2
data/ext/drx_ext.c CHANGED
@@ -1,6 +1,14 @@
1
1
  #include "ruby.h"
2
2
  #include "st.h"
3
3
 
4
+ /**
5
+ * Gets the Ruby's engine type of a variable.
6
+ */
7
+ static VALUE t_get_type(VALUE self, VALUE obj)
8
+ {
9
+ return INT2NUM(TYPE(obj));
10
+ }
11
+
4
12
  // Helper for t_get_iv_tbl().
5
13
  int record_var(st_data_t key, st_data_t value, VALUE hash) {
6
14
  // I originally did the following, but it breaks for object::Tk*. Perhaps these
@@ -78,7 +86,7 @@ static VALUE t_get_flags(VALUE self, VALUE obj)
78
86
 
79
87
  // Helper for t_get_m_tbl().
80
88
  int record_method(st_data_t key, st_data_t value, VALUE hash) {
81
- // @todo: Store something useful in the values.
89
+ // @todo: Store something useful in the values?
82
90
  rb_hash_aset(hash, key == ID_ALLOCATOR ? rb_str_new2("<Allocator>") : ID2SYM(key), INT2FIX(666));
83
91
  return ST_CONTINUE;
84
92
  }
@@ -110,14 +118,102 @@ static VALUE t_get_address(VALUE self, VALUE obj)
110
118
  return INT2NUM(obj);
111
119
  }
112
120
 
113
- /**
114
- * Gets the Ruby's engine type of a variable.
121
+ // {{{ Locating methods
122
+
123
+ #include "node.h"
124
+
125
+ #define RSTR(s) rb_str_new2(s)
126
+
127
+ static t_do_locate_method(NODE *ND_method) {
128
+ NODE *ND_scope = NULL, *ND_block = NULL;
129
+ VALUE place;
130
+ char line_s[20];
131
+
132
+ //
133
+ // The NODE_METHOD node
134
+ //
135
+
136
+ if (nd_type(ND_method) != NODE_METHOD/*0*/) {
137
+ return RSTR("I'm expecting a NODE_METHOD here...");
138
+ }
139
+
140
+ //
141
+ // The NODE_SCOPE node
142
+ //
143
+
144
+ ND_scope = ND_method->u2.node;
145
+
146
+ if (nd_type(ND_scope) == NODE_CFUNC/*2*/) {
147
+ return RSTR("That's a C function");
148
+ }
149
+
150
+ if (nd_type(ND_scope) == NODE_ATTRSET/*89*/) {
151
+ return RSTR("That's an attr setter");
152
+ }
153
+
154
+ if (nd_type(ND_scope) == NODE_FBODY/*1*/) {
155
+ return RSTR("That's an alias");
156
+ }
157
+
158
+ if (nd_type(ND_scope) == NODE_ZSUPER/*41*/) {
159
+ // @todo The DateTime clas has a lot of these.
160
+ return RSTR("That's a ZSUPER, whatver the heck it means!");
161
+ }
162
+
163
+ if (nd_type(ND_scope) != NODE_SCOPE/*3*/) {
164
+ printf("I'm expecting a NODE_SCOPE HERE (got %d instead)\n", nd_type(ND_scope));
165
+ return RSTR("I'm expecting a NODE_SCOPE HERE...");
166
+ }
167
+
168
+ //
169
+ // The NODE_BLOCK node
170
+ //
171
+
172
+ ND_block = ND_scope->u3.node;
173
+
174
+ if (nd_type(ND_block) != NODE_BLOCK/*4*/) {
175
+ return RSTR("I'm expecting a NODE_BLOCK here...");
176
+ }
177
+
178
+ sprintf(line_s, "%d:", nd_line(ND_block));
179
+ place = RSTR(line_s);
180
+ rb_str_cat2(place, ND_block->nd_file);
181
+
182
+ return place;
183
+ }
184
+
185
+ /*
186
+ * call-seq:
187
+ * Drx.locate_method(Date, "to_s") => str
188
+ *
189
+ * Locates the filename and line-number where a method was defined. Returns a
190
+ * string of the form "89:/path/to/file.rb", or nil if method doens't exist.
191
+ * If the method exist but isn't a Ruby method (i.e., if it's written in C),
192
+ * the string returned will include an erorr message, e.g. "That's a C
193
+ * function".
115
194
  */
116
- static VALUE t_get_type(VALUE self, VALUE obj)
195
+ static VALUE t_locate_method(VALUE self, VALUE obj, VALUE method_name)
117
196
  {
118
- return INT2NUM(TYPE(obj));
197
+ const char *c_name;
198
+ NODE *method_node;
199
+
200
+ if (TYPE(obj) != T_CLASS && TYPE(obj) != T_ICLASS && TYPE(obj) != T_MODULE) {
201
+ rb_raise(rb_eTypeError, "Only T_CLASS/T_MODULE is expected as the argument (got %d)", TYPE(obj));
202
+ }
203
+ if (!RCLASS(obj)->m_tbl) {
204
+ return Qnil;
205
+ }
206
+ c_name = StringValuePtr(method_name);
207
+ ID id = rb_intern(c_name);
208
+ if (st_lookup(RCLASS(obj)->m_tbl, id, &method_node)) {
209
+ return t_do_locate_method(method_node);
210
+ } else {
211
+ return Qnil;
212
+ }
119
213
  }
120
214
 
215
+ // }}}
216
+
121
217
  VALUE mDrx;
122
218
 
123
219
  void Init_drx_ext() {
@@ -130,6 +226,7 @@ void Init_drx_ext() {
130
226
  rb_define_module_function(mDrx, "get_address", t_get_address, 1);
131
227
  rb_define_module_function(mDrx, "get_type", t_get_type, 1);
132
228
  rb_define_module_function(mDrx, "get_ivar", t_get_ivar, 2);
229
+ rb_define_module_function(mDrx, "locate_method", t_locate_method, 2);
133
230
  rb_define_const(mDrx, "FL_SINGLETON", INT2FIX(FL_SINGLETON));
134
231
  rb_define_const(mDrx, "T_OBJECT", INT2FIX(T_OBJECT));
135
232
  rb_define_const(mDrx, "T_CLASS", INT2FIX(T_CLASS));
data/lib/drx_test.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'rubygems'
1
2
  require 'drxtk'
2
3
 
3
4
  require 'date'
@@ -20,6 +21,4 @@ Drx.examine(zmn)
20
21
  #############################
21
22
 
22
23
  Drx.examinetk(zmn)
23
-
24
- #Drx.examinetk(zmn)
25
24
  #Drx.examinetk("some_string")
data/lib/drxtk.rb CHANGED
@@ -4,7 +4,7 @@ require 'tk'
4
4
  module Drx
5
5
  def self.examinetk(obj)
6
6
  app = Drx::TkGUI::DrxWindow.new
7
- app.display_value(obj)
7
+ app.see(obj)
8
8
  app.run
9
9
  end
10
10
 
@@ -16,6 +16,9 @@ end
16
16
 
17
17
  module Drx
18
18
  module TkGUI
19
+
20
+ # The 'DRX_EDITOR_COMMAND' environment variable overrides this.
21
+ EDITOR_COMMAND = 'gedit +%d "%s"'
19
22
 
20
23
  class ScrolledListbox < TkFrame
21
24
  def initialize(*args, &block)
@@ -53,20 +56,26 @@ module Drx
53
56
 
54
57
  class DrxWindow
55
58
  def initialize
59
+ @stack = []
56
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
+ }
57
69
  @list = (ScrolledListbox.new(root) {
58
- #pack :side => 'left', :fill => 'y'
59
70
  pack :side => 'left', :fill => 'both', :expand => true
60
71
  }).the_list
61
72
  @list.width 52
62
73
  @list.height 25
63
74
  @list.focus
64
75
  @varsbox = (ScrolledListbox.new(root) {
65
- #pack :side => 'left', :fill => 'y'
66
76
  pack :side => 'left', :fill => 'both', :expand => true
67
77
  }).the_list
68
78
  @methodsbox = (ScrolledListbox.new(root) {
69
- #pack :side => 'left', :fill => 'y'
70
79
  pack :side => 'left', :fill => 'both', :expand => true
71
80
  }).the_list
72
81
 
@@ -75,15 +84,75 @@ module Drx
75
84
  display_variables(current_object)
76
85
  display_methods(current_object)
77
86
  }
87
+ @list.bind('ButtonRelease-3') {
88
+ back
89
+ }
90
+ @list.bind('Double-Button-1') {
91
+ descend_iclass
92
+ }
78
93
  @varsbox.bind('<ListboxSelect>') {
79
- inspect_variable(current_object, @varsbox.get_selection)
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)
80
110
  }
81
111
  end
82
112
 
83
- # def current_object=(obj)
84
- # @current_object = obj
85
- # end
86
-
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
+
87
156
  def current_object
88
157
  @current_object
89
158
  end
@@ -92,15 +161,12 @@ module Drx
92
161
  @varsbox.delete('0', 'end')
93
162
  if (Drx.has_iv_tbl(obj))
94
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/ }
95
166
  @varsbox.insert('end', *vars)
96
167
  end
97
168
  end
98
169
 
99
- def inspect_variable(obj, var_name)
100
- print "\n== Variable #{var_name}\n\n"
101
- p Drx.get_ivar(obj, var_name)
102
- end
103
-
104
170
  def display_methods(obj)
105
171
  @methodsbox.delete('0', 'end')
106
172
  if (Drx.is_class_like(obj))
@@ -109,14 +175,32 @@ module Drx
109
175
  end
110
176
  end
111
177
 
112
- def display_value(value)
178
+ def display_hierarchy(obj)
179
+ @list.delete('0', 'end')
113
180
  @objs = []
114
- Drx.examine(value) do |line, obj|
181
+ Drx.examine(obj) do |line, o|
115
182
  @list.insert('end', line)
116
- @objs << obj
183
+ @objs << o
117
184
  end
118
185
  end
119
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
+
120
204
  def run
121
205
  Tk.mainloop
122
206
  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.1
4
+ version: 0.0.2
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: 2009-02-03 00:00:00 +02:00
12
+ date: 2009-02-04 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies: []
15
15