looksee 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ == 0.1.0 2009-08-20
2
+
3
+ * Add methods undefined with Module#undef_method. Blue by default.
4
+
1
5
  == 0.0.2 2009-07-28
2
6
 
3
7
  * Added #grep to filter methods shown: lp(object).grep(/pattern/)
data/README.rdoc CHANGED
@@ -65,7 +65,8 @@ This defines a method +lp+ ("lookup path") which lets you do:
65
65
  frozen? nil? untaint
66
66
 
67
67
  It'll also color the methods according to whether they're public,
68
- protected, private, or overridden. So pretty. You gotta try it.
68
+ protected, private, undefined (using Module#undef_method), or
69
+ overridden. So pretty. You gotta try it.
69
70
 
70
71
  By default, it shows public and protected methods. Add private ones
71
72
  like so:
@@ -115,6 +115,23 @@ VALUE Looksee_internal_private_instance_methods(VALUE self, VALUE klass) {
115
115
  return internal_instance_methods(klass, NOEX_PRIVATE);
116
116
  }
117
117
 
118
+ static int add_method_if_undefined(ID method_name, NODE *body, VALUE *names) {
119
+ /* Module#undef_method sets body->nd_body to NULL. */
120
+ if (body && !body->nd_body)
121
+ rb_ary_push(*names, ID2SYM(method_name));
122
+ return ST_CONTINUE;
123
+ }
124
+
125
+ /*
126
+ * Return the list of undefined instance methods (as Symbols) of the
127
+ * given internal class.
128
+ */
129
+ VALUE Looksee_internal_undefined_instance_methods(VALUE self, VALUE klass) {
130
+ VALUE names = rb_ary_new();
131
+ st_foreach(RCLASS_M_TBL(klass), add_method_if_undefined, (st_data_t)&names);
132
+ return names;
133
+ }
134
+
118
135
  void Init_looksee(void) {
119
136
  VALUE mLooksee = rb_define_module("Looksee");
120
137
  rb_define_singleton_method(mLooksee, "internal_superclass", Looksee_internal_superclass, 1);
@@ -123,4 +140,5 @@ void Init_looksee(void) {
123
140
  rb_define_singleton_method(mLooksee, "internal_public_instance_methods", Looksee_internal_public_instance_methods, 1);
124
141
  rb_define_singleton_method(mLooksee, "internal_protected_instance_methods", Looksee_internal_protected_instance_methods, 1);
125
142
  rb_define_singleton_method(mLooksee, "internal_private_instance_methods", Looksee_internal_private_instance_methods, 1);
143
+ rb_define_singleton_method(mLooksee, "internal_undefined_instance_methods", Looksee_internal_undefined_instance_methods, 1);
126
144
  }
data/lib/looksee.rb CHANGED
@@ -32,8 +32,8 @@ require "looksee/version"
32
32
  #
33
33
  # +lp+ returns a LookupPath object, which has +inspect+ defined to
34
34
  # print things out pretty. By default, it shows public, protected,
35
- # and overridden methods. They're all colored, which makes showing
36
- # overridden methods not such a strange idea.
35
+ # undefined, and overridden methods. They're all colored, which makes
36
+ # showing overridden methods not such a strange idea.
37
37
  #
38
38
  # Some examples of the other shortcuts:
39
39
  #
@@ -66,9 +66,11 @@ module Looksee
66
66
  # * +:public+ - include public methods
67
67
  # * +:protected+ - include protected methods
68
68
  # * +:private+ - include private methods
69
+ # * +:undefined+ - include undefined methods (see Module#undef_method)
69
70
  # * +:overridden+ - include methods overridden by subclasses
70
71
  #
71
- # The default (if options is nil or omitted) is [:public].
72
+ # The default (if options is nil or omitted) is given by
73
+ # #default_lookup_path_options.
72
74
  #
73
75
  def lookup_path(object, *options)
74
76
  normalized_options = Looksee.default_lookup_path_options.dup
@@ -83,7 +85,8 @@ module Looksee
83
85
  #
84
86
  # The default options passed to lookup_path.
85
87
  #
86
- # Default: <tt>{:public => true, :protected => true, :overridden => true}</tt>
88
+ # Default: <tt>{:public => true, :protected => true, :undefined =>
89
+ # true, :overridden => true}</tt>
87
90
  #
88
91
  attr_accessor :default_lookup_path_options
89
92
 
@@ -104,6 +107,7 @@ module Looksee
104
107
  # * :public
105
108
  # * :protected
106
109
  # * :private
110
+ # * :undefined
107
111
  # * :overridden
108
112
  #
109
113
  # The values are format strings. They should all contain a single
@@ -116,6 +120,7 @@ module Looksee
116
120
  # :public => "\e[1;32m%s\e[0m",
117
121
  # :protected => "\e[1;33m%s\e[0m",
118
122
  # :private => "\e[1;31m%s\e[0m",
123
+ # :undefined => "\e[1;34m%s\e[0m",
119
124
  # :overridden => "\e[1;30m%s\e[0m",
120
125
  # }
121
126
  #
@@ -136,13 +141,14 @@ module Looksee
136
141
  end
137
142
  end
138
143
 
139
- self.default_lookup_path_options = {:public => true, :protected => true, :overridden => true}
144
+ self.default_lookup_path_options = {:public => true, :protected => true, :undefined => true, :overridden => true}
140
145
  self.default_width = 80
141
146
  self.styles = {
142
147
  :module => "\e[1;37m%s\e[0m",
143
148
  :public => "\e[1;32m%s\e[0m",
144
149
  :protected => "\e[1;33m%s\e[0m",
145
150
  :private => "\e[1;31m%s\e[0m",
151
+ :undefined => "\e[1;34m%s\e[0m",
146
152
  :overridden => "\e[1;30m%s\e[0m",
147
153
  }
148
154
 
@@ -162,6 +168,7 @@ module Looksee
162
168
  # :public
163
169
  # :protected
164
170
  # :private
171
+ # :undefined
165
172
  # :overridden
166
173
  #
167
174
  def self.for(object, options={})
@@ -226,6 +233,7 @@ module Looksee
226
233
  add_methods(Looksee.internal_public_instance_methods(@module).map{|sym| sym.to_s} , :public , seen) if options[:public ]
227
234
  add_methods(Looksee.internal_protected_instance_methods(@module).map{|sym| sym.to_s}, :protected, seen) if options[:protected]
228
235
  add_methods(Looksee.internal_private_instance_methods(@module).map{|sym| sym.to_s} , :private , seen) if options[:private ]
236
+ add_methods(Looksee.internal_undefined_instance_methods(@module).map{|sym| sym.to_s}, :undefined, seen) if options[:undefined]
229
237
  @methods.sort!
230
238
  end
231
239
 
@@ -256,7 +264,7 @@ module Looksee
256
264
 
257
265
  #
258
266
  # Yield each method along with its visibility (:public,
259
- # :private, :protected, or :overridden).
267
+ # :private, :protected, :undefined, or :overridden).
260
268
  #
261
269
  def each
262
270
  @methods.each do |name|
@@ -1,3 +1,3 @@
1
1
  module Looksee
2
- VERSION = '0.0.2'
2
+ VERSION = '0.1.0'
3
3
  end
data/looksee.gemspec CHANGED
@@ -2,17 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{looksee}
5
- s.version = "0.0.1"
5
+ s.version = "0.1.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["George Ogata"]
9
- s.date = %q{2009-07-05}
9
+ s.date = %q{2009-08-20}
10
10
  s.description = %q{Looksee lets you examine the method lookup path of objects in ways not
11
11
  possible in plain ruby.}
12
12
  s.email = ["george.ogata@gmail.com"]
13
13
  s.extensions = ["ext/looksee/extconf.rb"]
14
14
  s.extra_rdoc_files = ["History.txt", "Manifest.txt"]
15
- s.files = [".autotest", "History.txt", "Manifest.txt", "README.rdoc", "Rakefile", "ext/looksee/extconf.rb", "ext/looksee/looksee.c", "ext/looksee/node-1.9.h", "lib/looksee.rb", "lib/looksee/shortcuts.rb", "lib/looksee/version.rb", "script/console", "script/destroy", "script/generate", "spec/looksee_spec.rb", "spec/spec_helper.rb", "tasks/extconf.rake", "tasks/extconf/looksee.rake"]
15
+ s.files = [".autotest", "History.txt", "Manifest.txt", "README.rdoc", "Rakefile", "ext/looksee/extconf.rb", "ext/looksee/looksee.c", "ext/looksee/node-1.9.h", "lib/looksee.rb", "lib/looksee/shortcuts.rb", "lib/looksee/version.rb", "lib/looksee/wirble_compatibility.rb", "looksee.gemspec", "script/console", "script/destroy", "script/generate", "spec/looksee_spec.rb", "spec/spec_helper.rb", "spec/wirble_compatibility_spec.rb", "tasks/extconf.rake", "tasks/extconf/looksee.rake"]
16
16
  s.homepage = %q{http://github.com/oggy/looksee}
17
17
  s.rdoc_options = ["--main", "README.rdoc"]
18
18
  s.require_paths = ["lib", "ext/looksee"]
@@ -25,18 +25,18 @@ possible in plain ruby.}
25
25
  s.specification_version = 3
26
26
 
27
27
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
- s.add_development_dependency(%q<newgem>, [">= 1.5.1"])
28
+ s.add_development_dependency(%q<newgem>, [">= 1.5.2"])
29
29
  s.add_development_dependency(%q<rspec>, [">= 1.2.7"])
30
30
  s.add_development_dependency(%q<mocha>, [">= 0.9.5"])
31
31
  s.add_development_dependency(%q<hoe>, [">= 2.3.2"])
32
32
  else
33
- s.add_dependency(%q<newgem>, [">= 1.5.1"])
33
+ s.add_dependency(%q<newgem>, [">= 1.5.2"])
34
34
  s.add_dependency(%q<rspec>, [">= 1.2.7"])
35
35
  s.add_dependency(%q<mocha>, [">= 0.9.5"])
36
36
  s.add_dependency(%q<hoe>, [">= 2.3.2"])
37
37
  end
38
38
  else
39
- s.add_dependency(%q<newgem>, [">= 1.5.1"])
39
+ s.add_dependency(%q<newgem>, [">= 1.5.2"])
40
40
  s.add_dependency(%q<rspec>, [">= 1.2.7"])
41
41
  s.add_dependency(%q<mocha>, [">= 0.9.5"])
42
42
  s.add_dependency(%q<hoe>, [">= 2.3.2"])
data/spec/looksee_spec.rb CHANGED
@@ -171,16 +171,61 @@ describe Looksee do
171
171
  it_should_list_methods_with_visibility :private
172
172
  it_should_not_list_methods_with_visibility :public, :protected
173
173
  end
174
+
175
+ describe ".internal_undefined_instance_methods" do
176
+ it "should return the list of undefined instance methods directly on a class" do
177
+ temporary_class :C
178
+ C.send(:define_method, :f){}
179
+ C.send(:undef_method, :f)
180
+ Looksee.internal_undefined_instance_methods(C).should == [:f]
181
+ end
182
+
183
+ it "should return the list of undefined instance methods directly on a module" do
184
+ temporary_module :M
185
+ M.send(:define_method, :f){}
186
+ M.send(:undef_method, :f)
187
+ Looksee.internal_undefined_instance_methods(M).should == [:f]
188
+ end
189
+
190
+ it "should return the list of undefined instance methods directly on a singleton class" do
191
+ temporary_class :C
192
+ c = C.new
193
+ c.singleton_class.send(:define_method, :f){}
194
+ c.singleton_class.send(:undef_method, :f)
195
+ Looksee.internal_undefined_instance_methods(c.singleton_class).should == [:f]
196
+ end
197
+
198
+ it "should return the list of undefined instance methods directly on a class' singleton class" do
199
+ temporary_class :C
200
+ C.singleton_class.send(:define_method, :f){}
201
+ C.singleton_class.send(:undef_method, :f)
202
+ Looksee.internal_undefined_instance_methods(C.singleton_class).should == [:f]
203
+ end
204
+
205
+ it "should not return defined methods" do
206
+ temporary_class :C
207
+ C.send(:define_method, :f){}
208
+ Looksee.internal_undefined_instance_methods(C).should == []
209
+ end
210
+
211
+ it "should not return removed methods" do
212
+ temporary_class :C
213
+ C.send(:define_method, :f){}
214
+ C.send(:remove_method, :f)
215
+ Looksee.internal_undefined_instance_methods(C).should == []
216
+ end
217
+ end
174
218
  end
175
219
  end
176
220
 
177
221
  describe Looksee::LookupPath do
178
222
  include TemporaryClasses
179
223
 
180
- def stub_methods(mod, public, protected, private)
224
+ def stub_methods(mod, public, protected, private, undefined)
181
225
  Looksee.stubs(:internal_public_instance_methods ).with(mod).returns(public)
182
226
  Looksee.stubs(:internal_protected_instance_methods).with(mod).returns(protected)
183
227
  Looksee.stubs(:internal_private_instance_methods ).with(mod).returns(private)
228
+ Looksee.stubs(:internal_undefined_instance_methods).with(mod).returns(undefined)
184
229
  end
185
230
 
186
231
  describe "#entries" do
@@ -197,8 +242,8 @@ describe Looksee::LookupPath do
197
242
  it "should only include methods matching the given regexp" do
198
243
  temporary_class :C
199
244
  temporary_class :D
200
- stub_methods(C, ['axbyc', 'xy'], [], [])
201
- stub_methods(D, ['axbyc', 'xdy'], [], [])
245
+ stub_methods(C, ['axbyc', 'xy'], [], [], [])
246
+ stub_methods(D, ['axbyc', 'xdy'], [], [], [])
202
247
  object = Object.new
203
248
  Looksee.stubs(:lookup_modules).with(object).returns([C, D])
204
249
  lookup_path = Looksee::LookupPath.for(object, :public => true, :overridden => true).grep(/x.y/)
@@ -210,8 +255,8 @@ describe Looksee::LookupPath do
210
255
  it "should only include methods including the given string" do
211
256
  temporary_class :C
212
257
  temporary_class :D
213
- stub_methods(C, ['axxa', 'axa'], [], [])
214
- stub_methods(D, ['bxxb', 'axxa'], [], [])
258
+ stub_methods(C, ['axxa', 'axa'], [], [], [])
259
+ stub_methods(D, ['bxxb', 'axxa'], [], [], [])
215
260
  object = Object.new
216
261
  Looksee.stubs(:lookup_modules).with(object).returns([C, D])
217
262
  lookup_path = Looksee::LookupPath.for(object, :public => true, :overridden => true).grep('xx')
@@ -238,8 +283,8 @@ describe Looksee::LookupPath do
238
283
  end
239
284
  @object = Object.new
240
285
  Looksee.stubs(:lookup_modules).with(@object).returns([C, M])
241
- stub_methods(C, ['public1', 'public2'], ['protected1', 'protected2'], ['private1', 'private2'])
242
- stub_methods(M, ['public1', 'public2'], ['protected1', 'protected2'], ['private1', 'private2'])
286
+ stub_methods(C, ['public1', 'public2'], ['protected1', 'protected2'], ['private1', 'private2'], ['undefined1', 'undefined2'])
287
+ stub_methods(M, ['public1', 'public2'], ['protected1', 'protected2'], ['private1', 'private2'], ['undefined1', 'undefined2'])
243
288
  end
244
289
 
245
290
  it "should show only public instance methods when only public methods are requested" do
@@ -272,6 +317,16 @@ describe Looksee::LookupPath do
272
317
  EOS
273
318
  end
274
319
 
320
+ it "should show modules and undefined instance methods when only undefined methods are requested" do
321
+ lookup_path = Looksee::LookupPath.for(@object, :undefined => true, :overridden => true)
322
+ lookup_path.inspect.should == <<-EOS.demargin.chomp
323
+ |C
324
+ | undefined1 undefined2
325
+ |M
326
+ | undefined1 undefined2
327
+ EOS
328
+ end
329
+
275
330
  it "should show modules with public and private instance methods when only public and private methods are requested" do
276
331
  lookup_path = Looksee::LookupPath.for(@object, :public => true, :private => true, :overridden => true)
277
332
  lookup_path.inspect.should == <<-EOS.demargin.chomp
@@ -284,7 +339,7 @@ describe Looksee::LookupPath do
284
339
 
285
340
  it "should show singleton classes as class names in brackets" do
286
341
  Looksee.stubs(:lookup_modules).with(C).returns([C.singleton_class])
287
- stub_methods(C.singleton_class, ['public1', 'public2'], [], [])
342
+ stub_methods(C.singleton_class, ['public1', 'public2'], [], [], [])
288
343
  lookup_path = Looksee::LookupPath.for(C, :public => true)
289
344
  lookup_path.inspect.should == <<-EOS.demargin.chomp
290
345
  |[C]
@@ -294,7 +349,7 @@ describe Looksee::LookupPath do
294
349
 
295
350
  it "should handle singleton classes of singleton classes correctly" do
296
351
  Looksee.stubs(:lookup_modules).with(C.singleton_class).returns([C.singleton_class.singleton_class])
297
- stub_methods(C.singleton_class.singleton_class, ['public1', 'public2'], [], [])
352
+ stub_methods(C.singleton_class.singleton_class, ['public1', 'public2'], [], [], [])
298
353
  lookup_path = Looksee::LookupPath.for(C.singleton_class, :public => true)
299
354
  lookup_path.inspect.should == <<-EOS.demargin.chomp
300
355
  |[[C]]
@@ -303,7 +358,7 @@ describe Looksee::LookupPath do
303
358
  end
304
359
 
305
360
  it "should not show any blank lines if a module has no methods" do
306
- stub_methods(C, [], [], [])
361
+ stub_methods(C, [], [], [], [])
307
362
  lookup_path = Looksee::LookupPath.for(@object, :public => true, :overridden => true)
308
363
  lookup_path.inspect.should == <<-EOS.demargin.chomp
309
364
  |C
@@ -320,6 +375,7 @@ describe Looksee::LookupPath do
320
375
  :public => "{%s}",
321
376
  :protected => "[%s]",
322
377
  :private => "<%s>",
378
+ :undefined => "~%s~",
323
379
  :overridden => "(%s)",
324
380
  }
325
381
  Looksee.stubs(:styles).returns(styles)
@@ -328,11 +384,11 @@ describe Looksee::LookupPath do
328
384
  it "should delimit each word with the configured delimiters" do
329
385
  temporary_class :C
330
386
  Looksee.stubs(:lookup_modules).returns([C])
331
- stub_methods(C, ['public'], ['protected'], ['private'])
332
- lookup_path = Looksee::LookupPath.for(Object.new, :public => true, :protected => true, :private => true, :overridden => true)
387
+ stub_methods(C, ['public'], ['protected'], ['private'], ['undefined'])
388
+ lookup_path = Looksee::LookupPath.for(Object.new, :public => true, :protected => true, :private => true, :undefined => true, :overridden => true)
333
389
  lookup_path.inspect.should == <<-EOS.demargin.chomp
334
390
  |\`C\'
335
- | <private> [protected] {public}
391
+ | <private> [protected] {public} ~undefined~
336
392
  EOS
337
393
  end
338
394
  end
@@ -341,7 +397,7 @@ describe Looksee::LookupPath do
341
397
  it "should wrap method lists at the configured number of columns, sorting vertically first, and aligning into a grid" do
342
398
  temporary_class :C
343
399
  Looksee.stubs(:lookup_modules).returns([C])
344
- stub_methods(C, %w'aa b c dd ee f g hh i', [], [])
400
+ stub_methods(C, %w'aa b c dd ee f g hh i', [], [], [])
345
401
  lookup_path = Looksee::LookupPath.for(Object.new, :public => true)
346
402
  lookup_path.inspect(:width => 20).should == <<-EOS.demargin.chomp
347
403
  |C
@@ -354,8 +410,8 @@ describe Looksee::LookupPath do
354
410
  temporary_class :A
355
411
  temporary_class :B
356
412
  Looksee.stubs(:lookup_modules).returns([A, B])
357
- stub_methods(A, ['a', 'long_long_long_long_name'], [], [])
358
- stub_methods(B, ['long_long_long', 'short'], [], [])
413
+ stub_methods(A, ['a', 'long_long_long_long_name'], [], [], [])
414
+ stub_methods(B, ['long_long_long', 'short'], [], [], [])
359
415
  lookup_path = Looksee::LookupPath.for(Object.new, :public => true)
360
416
  lookup_path.inspect.should == <<-EOS.demargin.chomp
361
417
  |A
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: looksee
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - George Ogata
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-01 00:00:00 +12:00
12
+ date: 2009-08-20 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 1.5.1
23
+ version: 1.5.2
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec