looksee 0.0.2 → 0.1.0

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/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