bitclust-core 0.5.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.
Files changed (127) hide show
  1. data/ChangeLog +2907 -0
  2. data/Gemfile +7 -0
  3. data/README +21 -0
  4. data/Rakefile +20 -0
  5. data/bin/bitclust +14 -0
  6. data/bin/refe +36 -0
  7. data/bitclust-dev.gemspec +33 -0
  8. data/bitclust.gemspec +30 -0
  9. data/config.in +23 -0
  10. data/config.ru +48 -0
  11. data/config.ru.sample +31 -0
  12. data/data/bitclust/catalog/ja_JP.EUC-JP +78 -0
  13. data/data/bitclust/catalog/ja_JP.UTF-8 +78 -0
  14. data/data/bitclust/template.lillia/class +98 -0
  15. data/data/bitclust/template.lillia/class-index +28 -0
  16. data/data/bitclust/template.lillia/doc +48 -0
  17. data/data/bitclust/template.lillia/layout +19 -0
  18. data/data/bitclust/template.lillia/library +129 -0
  19. data/data/bitclust/template.lillia/library-index +32 -0
  20. data/data/bitclust/template.lillia/method +20 -0
  21. data/data/bitclust/template.lillia/rd_file +6 -0
  22. data/data/bitclust/template.offline/class +67 -0
  23. data/data/bitclust/template.offline/class-index +28 -0
  24. data/data/bitclust/template.offline/doc +13 -0
  25. data/data/bitclust/template.offline/function +22 -0
  26. data/data/bitclust/template.offline/function-index +24 -0
  27. data/data/bitclust/template.offline/layout +18 -0
  28. data/data/bitclust/template.offline/library +87 -0
  29. data/data/bitclust/template.offline/library-index +32 -0
  30. data/data/bitclust/template.offline/method +21 -0
  31. data/data/bitclust/template.offline/rd_file +6 -0
  32. data/data/bitclust/template/class +133 -0
  33. data/data/bitclust/template/class-index +30 -0
  34. data/data/bitclust/template/doc +14 -0
  35. data/data/bitclust/template/function +21 -0
  36. data/data/bitclust/template/function-index +25 -0
  37. data/data/bitclust/template/layout +19 -0
  38. data/data/bitclust/template/library +89 -0
  39. data/data/bitclust/template/library-index +35 -0
  40. data/data/bitclust/template/method +24 -0
  41. data/data/bitclust/template/opensearchdescription +10 -0
  42. data/data/bitclust/template/search +57 -0
  43. data/lib/bitclust.rb +9 -0
  44. data/lib/bitclust/app.rb +129 -0
  45. data/lib/bitclust/classentry.rb +425 -0
  46. data/lib/bitclust/compat.rb +39 -0
  47. data/lib/bitclust/completion.rb +531 -0
  48. data/lib/bitclust/crossrubyutils.rb +91 -0
  49. data/lib/bitclust/database.rb +181 -0
  50. data/lib/bitclust/docentry.rb +83 -0
  51. data/lib/bitclust/entry.rb +223 -0
  52. data/lib/bitclust/exception.rb +38 -0
  53. data/lib/bitclust/functiondatabase.rb +115 -0
  54. data/lib/bitclust/functionentry.rb +81 -0
  55. data/lib/bitclust/functionreferenceparser.rb +76 -0
  56. data/lib/bitclust/htmlutils.rb +80 -0
  57. data/lib/bitclust/interface.rb +87 -0
  58. data/lib/bitclust/libraryentry.rb +211 -0
  59. data/lib/bitclust/lineinput.rb +165 -0
  60. data/lib/bitclust/messagecatalog.rb +95 -0
  61. data/lib/bitclust/methoddatabase.rb +401 -0
  62. data/lib/bitclust/methodentry.rb +202 -0
  63. data/lib/bitclust/methodid.rb +209 -0
  64. data/lib/bitclust/methodsignature.rb +82 -0
  65. data/lib/bitclust/nameutils.rb +236 -0
  66. data/lib/bitclust/parseutils.rb +60 -0
  67. data/lib/bitclust/preprocessor.rb +273 -0
  68. data/lib/bitclust/rdcompiler.rb +507 -0
  69. data/lib/bitclust/refsdatabase.rb +66 -0
  70. data/lib/bitclust/requesthandler.rb +330 -0
  71. data/lib/bitclust/ridatabase.rb +349 -0
  72. data/lib/bitclust/rrdparser.rb +522 -0
  73. data/lib/bitclust/runner.rb +143 -0
  74. data/lib/bitclust/screen.rb +554 -0
  75. data/lib/bitclust/searcher.rb +518 -0
  76. data/lib/bitclust/server.rb +59 -0
  77. data/lib/bitclust/simplesearcher.rb +84 -0
  78. data/lib/bitclust/subcommand.rb +746 -0
  79. data/lib/bitclust/textutils.rb +51 -0
  80. data/lib/bitclust/version.rb +3 -0
  81. data/packer.rb +224 -0
  82. data/refe2.gemspec +29 -0
  83. data/server.exe +0 -0
  84. data/server.exy +159 -0
  85. data/server.rb +10 -0
  86. data/setup.rb +1596 -0
  87. data/standalone.rb +193 -0
  88. data/test/run_test.rb +15 -0
  89. data/test/test_bitclust.rb +81 -0
  90. data/test/test_entry.rb +39 -0
  91. data/test/test_functiondatabase.rb +55 -0
  92. data/test/test_libraryentry.rb +31 -0
  93. data/test/test_methoddatabase.rb +81 -0
  94. data/test/test_methodsignature.rb +14 -0
  95. data/test/test_nameutils.rb +324 -0
  96. data/test/test_preprocessor.rb +84 -0
  97. data/test/test_rdcompiler.rb +534 -0
  98. data/test/test_refsdatabase.rb +76 -0
  99. data/test/test_rrdparser.rb +26 -0
  100. data/test/test_runner.rb +102 -0
  101. data/test/test_simplesearcher.rb +48 -0
  102. data/theme/default/images/external.png +0 -0
  103. data/theme/default/rurema.png +0 -0
  104. data/theme/default/style.css +288 -0
  105. data/theme/default/test.css +254 -0
  106. data/theme/lillia/rurema.png +0 -0
  107. data/theme/lillia/style.css +331 -0
  108. data/theme/lillia/test.css +254 -0
  109. data/tools/bc-ancestors.rb +153 -0
  110. data/tools/bc-checkparams.rb +246 -0
  111. data/tools/bc-classes.rb +80 -0
  112. data/tools/bc-convert.rb +165 -0
  113. data/tools/bc-list.rb +63 -0
  114. data/tools/bc-methods.rb +171 -0
  115. data/tools/bc-preproc.rb +42 -0
  116. data/tools/bc-rdoc.rb +343 -0
  117. data/tools/bc-tochm.rb +301 -0
  118. data/tools/bc-tohtml.rb +125 -0
  119. data/tools/bc-tohtmlpackage.rb +241 -0
  120. data/tools/check-signature.rb +19 -0
  121. data/tools/forall-ruby.rb +20 -0
  122. data/tools/gencatalog.rb +69 -0
  123. data/tools/statrefm.rb +98 -0
  124. data/tools/stattodo.rb +150 -0
  125. data/tools/update-database.rb +146 -0
  126. data/view.cgi +6 -0
  127. metadata +222 -0
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pathname'
4
+
5
+ bindir = Pathname.new(__FILE__).realpath.dirname
6
+ $LOAD_PATH.unshift((bindir + '../lib').realpath)
7
+
8
+ require 'bitclust/crossrubyutils'
9
+ require 'optparse'
10
+
11
+ include BitClust::CrossRubyUtils
12
+
13
+ def main
14
+ rejects = []
15
+ @verbose = false
16
+ opts = OptionParser.new
17
+ opts.banner = "Usage: #{File.basename($0, '.*')} [-r<lib>] <lib>"
18
+ opts.on('-r', '--reject=LIB', 'Reject library LIB') {|lib|
19
+ rejects.concat lib.split(',')
20
+ }
21
+ opts.on('-v', '--verbose', 'Show all ruby version.') {
22
+ @verbose = true
23
+ }
24
+ opts.on('--help', 'Prints this message and quit.') {
25
+ puts opts.help
26
+ exit 0
27
+ }
28
+ begin
29
+ opts.parse!(ARGV)
30
+ rescue OptionParser::ParseError => err
31
+ $stderr.puts err.message
32
+ exit 1
33
+ end
34
+ unless ARGV.size == 1
35
+ $stderr.puts 'wrong number of arguments'
36
+ $stderr.puts opts.help
37
+ exit 1
38
+ end
39
+ lib = ARGV[0]
40
+ print_crossruby_table {|ruby| defined_classes(ruby, lib, rejects) }
41
+ end
42
+
43
+ def defined_classes(ruby, lib, rejects)
44
+ output = `#{ruby} -e '
45
+ def class_extent
46
+ result = []
47
+ ObjectSpace.each_object(Module) do |c|
48
+ result.push c
49
+ end
50
+ result
51
+ end
52
+
53
+ %w(#{rejects.join(" ")}).each do |lib|
54
+ begin
55
+ require lib
56
+ rescue LoadError
57
+ end
58
+ end
59
+ if "#{lib}" == "_builtin"
60
+ class_extent().each do |c|
61
+ puts c
62
+ end
63
+ else
64
+ before = class_extent()
65
+ begin
66
+ require "#{lib}"
67
+ rescue LoadError
68
+ $stderr.puts "\#{RUBY_VERSION} (\#{RUBY_RELEASE_DATE}): library not exist: #{lib}"
69
+ exit
70
+ end
71
+ after = class_extent()
72
+ (after - before).each do |c|
73
+ puts c
74
+ end
75
+ end
76
+ '`
77
+ output.split
78
+ end
79
+
80
+ main
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ $KCODE = 'UTF-8' unless Object.const_defined?(:Encoding)
5
+
6
+ require 'stringio'
7
+ require 'fileutils'
8
+ require 'tmpdir'
9
+ require 'optparse'
10
+
11
+ def main
12
+ mode = :output
13
+ parser = OptionParser.new
14
+ parser.banner = "Usage: #{File.basename($0, '.*')} [--diff] [file...]"
15
+ parser.on('--diff', 'Show the diff between original file and output') {
16
+ mode = :diff
17
+ }
18
+ parser.on('--inplace', 'edit input files in-place (make backup)') {
19
+ mode = :inplace
20
+ }
21
+ parser.on('--help') {
22
+ puts parser.help
23
+ exit
24
+ }
25
+ begin
26
+ parser.parse!
27
+ rescue OptionParser::ParseError => err
28
+ $stderr.puts err.message
29
+ exit 1
30
+ end
31
+ case mode
32
+ when :output
33
+ do_convert ARGF
34
+ when :diff
35
+ ARGV.each do |path|
36
+ diff_output path
37
+ end
38
+ when :inplace
39
+ ARGV.each do |path|
40
+ inplace_edit path
41
+ end
42
+ else
43
+ raise "must not happen: mode=#{mode.inspect}"
44
+ end
45
+ end
46
+
47
+ def inplace_edit(path)
48
+ str = convert_file(path)
49
+ File.rename path, path + '.bak'
50
+ File.open(path, 'w') {|f|
51
+ f.write str
52
+ }
53
+ end
54
+
55
+ def diff_output(path)
56
+ tmppath = "#{Dir.tmpdir}/bc-convert-diff"
57
+ File.open(tmppath, 'w') {|f|
58
+ f.write convert_file(path)
59
+ }
60
+ system 'diff', '-u', path, tmppath
61
+ ensure
62
+ FileUtils.rm_f tmppath
63
+ end
64
+
65
+ def convert_file(path)
66
+ File.open(path) {|f| convert(f) }
67
+ end
68
+
69
+ def convert(f)
70
+ buf = StringIO.new
71
+ do_convert f, buf
72
+ buf.string
73
+ end
74
+
75
+ def do_convert(f, out = $stdout)
76
+ f.each do |line|
77
+ case line
78
+ when /\A\#@/
79
+ out.puts line
80
+ when /\A\#/
81
+ out.puts '#@' + line
82
+ when /\A---\s/
83
+ sig = convert_signature(line.sub(/\A---/, '').sub(/\(\(<.*?>\)\)/i, '').strip)
84
+ out.puts "--- #{sig}"
85
+ if meta = line.slice(/\(\(<.*?>\)\)/i)
86
+ out.puts
87
+ out.puts meta
88
+ out.puts
89
+ end
90
+ else
91
+ out.puts convert_link(line.rstrip)
92
+ end
93
+ end
94
+ end
95
+
96
+ def convert_signature(sig)
97
+ case sig
98
+ when /\A([\w:\.\#]+[?!]?)\s*(?:[\(\{]|--|->|\z)/
99
+ # name(arg), name{}, name,
100
+ # name() -- obsolete
101
+ # name() -> return value type
102
+ sig
103
+ when /\A[\w:]+[\.\#]([+\-<>=~*^&|%\/]+)/ # Complex#+
104
+ sig
105
+ when /\Aself\s*(==|===|=~)\s*(\w+)/ # self == other
106
+ "#{$1}(#{$2})"
107
+ when /\A([\w:\.\#]+)\s*\=(\(|\s*\w+)?/ # name=
108
+ "#{remove_class_spec($1)}=(#{remove_paren($2.to_s.strip)})"
109
+ when /\A\w+\[(.*)\]=(.*)/ # self[key]=
110
+ "[]=(#{$1}, #{$2.strip})"
111
+ when /\A[\w\:]+\[(.*)\]/ # self[key]
112
+ "[](#{$1})"
113
+ when /\Aself\s*([+\-<>=~*^&|%\/]+)\s*(\w+)/ # self + other
114
+ "#{$1}(#{$2})"
115
+ when /\A([+\-~`])\s*\w+/ # ~ self
116
+ case op = $1
117
+ when '+', '-' then op + '@'
118
+ else op
119
+ end
120
+ when /\A(?:[\w:]+[\.\#])?(\[\]=?)/ # Matrix.[](i)
121
+ sig
122
+ when /\A([+\-<>=~*^&|%]+)/ # +(m)
123
+ sig
124
+ when /\A([A-Z]\w+\*)/ # HKEY_*
125
+ sig
126
+ when /\Aself([+\-<>=~*^&|%\/\[\]]+)\(\w/ # self+(other)
127
+ sig.sub(/\Aself/, '')
128
+ else
129
+ $stderr.puts "warning: unknown method signature: #{sig.inspect}"
130
+ sig
131
+ end
132
+ end
133
+
134
+ def remove_class_spec(str)
135
+ str.sub(/\A[A-Z]\w*(?:::[A-Z]\w*)*[\.\#]/, '')
136
+ end
137
+
138
+ def remove_paren(str)
139
+ str.sub(/\A\(/, '').sub(/\)\z/, '')
140
+ end
141
+
142
+ def convert_link(line)
143
+ line.gsub(/\(\(\{(.*?)\}\)\)/) { $1 }\
144
+ .gsub(/\(\(\|(.*?)\|\)\)/) { $1 }\
145
+ .gsub(/\(\(<(.*?)>\)\)/) { convert_href($1) }
146
+ end
147
+
148
+ def convert_href(link)
149
+ case link
150
+ when /\Atrap::(.*)/ then "[[trap:#{$1}]]"
151
+ when /\Aruby 1\.\S+ feature/ then "((<#{link}>))"
152
+ when /\Aobsolete/ then "((<obsolete>))"
153
+ when /\A組み込み変数\/(.*)/u then "[[m:#{$1}]]"
154
+ when /\A組み込み定数\/(.*)/u then "[[m:Kernel::#{$1}]]"
155
+ when /\A組み込み関数\/(.*)/u then "[[m:Kernel\##{$1}]]"
156
+ when /\A([\w:]+[\#\.][^|]+)\|/ then "[[m:#{$1}]]"
157
+ when /\A(.*?)\|manual page\z/ then "[[man:#{$1}]]"
158
+ when /\A([\w:]+)\/(.*)\z/n then "[[m:#{$1}\##{$2}]]"
159
+ when /\A([A-Z][\w:]*)\z/ then "[[c:#{$1}]]"
160
+ else
161
+ "[[unknown:#{link}]]"
162
+ end
163
+ end
164
+
165
+ main
data/tools/bc-list.rb ADDED
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pathname'
4
+
5
+ bindir = Pathname.new(__FILE__).realpath.dirname
6
+ $LOAD_PATH.unshift((bindir + '../lib').realpath)
7
+
8
+ require 'bitclust'
9
+ require 'optparse'
10
+
11
+ def main
12
+ check_only = false
13
+ parser = OptionParser.new
14
+ parser.banner = "Usage: #{File.basename($0, '.*')} <file>..."
15
+ parser.on('-c', '--check-only', 'Check syntax and output status.') {
16
+ check_only = true
17
+ }
18
+ parser.on('--help', 'Prints this message and quit.') {
19
+ puts parser.help
20
+ exit
21
+ }
22
+ begin
23
+ parser.parse!
24
+ rescue OptionParser::ParseError => err
25
+ $stderr.puts err.message
26
+ exit 1
27
+ end
28
+
29
+ success = true
30
+ ARGV.each do |path|
31
+ begin
32
+ lib = BitClust::RRDParser.parse_stdlib_file(path)
33
+ if check_only
34
+ $stderr.puts "#{path}: OK"
35
+ else
36
+ show_library lib
37
+ end
38
+ rescue BitClust::WriterError => err
39
+ raise if $DEBUG
40
+ $stderr.puts "#{File.basename($0, '.*')}: FAIL: #{err.message}"
41
+ success = false
42
+ end
43
+ end
44
+ exit success
45
+ end
46
+
47
+ def show_library(lib)
48
+ puts "= Library #{lib.name}"
49
+ lib.classes.each do |c|
50
+ puts "#{c.type} #{c.name}"
51
+ c.each do |m|
52
+ puts "\t* #{m.klass.name}#{m.typemark}#{m.names.join(',')}"
53
+ end
54
+ end
55
+ unless lib.methods.empty?
56
+ puts "Additional Methods:"
57
+ lib.methods.each do |m|
58
+ puts "\t* #{m.klass.name}#{m.typemark}#{m.names.join(',')}"
59
+ end
60
+ end
61
+ end
62
+
63
+ main
@@ -0,0 +1,171 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # bc-methods.rb -- list all methods of existing rubys.
4
+ #
5
+ # This program is derived from bc-vdtb.rb, posted in
6
+ # [ruby-reference-manual:160] by sheepman.
7
+ #
8
+
9
+ require 'pathname'
10
+
11
+ bindir = Pathname.new(__FILE__).realpath.dirname
12
+ $LOAD_PATH.unshift((bindir + '../lib').realpath)
13
+
14
+ require 'bitclust'
15
+ require 'bitclust/crossrubyutils'
16
+ require 'optparse'
17
+
18
+ include BitClust::CrossRubyUtils
19
+
20
+ def main
21
+ @requires = []
22
+ @verbose = false
23
+ @ver = RUBY_VERSION
24
+ mode = :list
25
+ target = nil
26
+ opts = OptionParser.new
27
+ opts.banner = "Usage: #{File.basename($0, '.*')} [-r<lib>] <classname>"
28
+ opts.on('-r LIB', 'Requires library LIB') {|lib|
29
+ @requires.push lib
30
+ }
31
+ opts.on('-v', '--verbose', "Prints each ruby's version") {
32
+ @verbose = true
33
+ }
34
+ opts.on('--diff=RDFILE', 'RD file name') {|path|
35
+ mode = :diff
36
+ target = path
37
+ }
38
+ opts.on('-c', '') {
39
+ @content = true
40
+ require 'bitclust/ridatabase'
41
+ }
42
+ opts.on('--ruby=[VER]', "The version of Ruby interpreter"){|ver|
43
+ @ver = ver
44
+ }
45
+ opts.on('--ri-database', 'The path of ri database'){|path|
46
+ @ri_path = path
47
+ }
48
+ opts.on('--help', 'Prints this message and quit.') {
49
+ puts opts.help
50
+ exit 0
51
+ }
52
+ begin
53
+ opts.parse!(ARGV)
54
+ rescue OptionParser::ParseError => err
55
+ $stderr.puts err.message
56
+ exit 1
57
+ end
58
+ unless ARGV.size == 1
59
+ $stderr.puts "wrong number of arguments"
60
+ $stderr.puts opts.help
61
+ exit 1
62
+ end
63
+ classname = ARGV[0]
64
+
65
+ case mode
66
+ when :list
67
+ print_crossruby_table {|ruby| defined_methods(ruby, classname) }
68
+ when :diff
69
+ unless ruby = get_ruby(@ver)
70
+ raise "Not found Ruby interpreter of the given version"
71
+ end
72
+ keys = defined_methods(ruby, classname)
73
+ lib = BitClust::RRDParser.parse_stdlib_file(target, { 'version' => @ver })
74
+ c = lib.fetch_class(classname)
75
+ list0 = lib.classes.find_all{|c0| /\A#{classname}\b/o =~ c0.name }
76
+ list0 = c.entries + list0
77
+ list = list0.map {|ent| ent.labels.map {|n| expand_mf(n) } }.flatten
78
+ if @content
79
+ ri = @ri_path ? RiDatabase.open(@ri_path, nil) : RiDatabase.open_system_db
80
+ ri.current_class = c.name
81
+ mthds = ( ri.singleton_methods + ri.instance_methods )
82
+ fmt = Formatter.new
83
+ (keys - list).sort.each do |name|
84
+ mthd = mthds.find{|m| name == m.fullname }
85
+ if mthd
86
+ puts fmt.method_info(mthd.entry)
87
+ else
88
+ name = name.sub(/\A\w+#/, '')
89
+ puts "--- #{name}\n\#@todo\n\n"
90
+ end
91
+ end
92
+ else
93
+ (keys - list).sort.each do |name|
94
+ puts "-#{name}"
95
+ end
96
+ (list - keys).sort.each do |name|
97
+ puts "+#{name}"
98
+ end
99
+ end
100
+ else
101
+ raise "must not happen: #{mode.inspect}"
102
+ end
103
+ end
104
+
105
+ def expand_mf(n)
106
+ if /\.\#/ =~ n
107
+ [n.sub(/\.\#/, '.'), n.sub(/\.\#/, '#')]
108
+ else
109
+ n
110
+ end
111
+ end
112
+
113
+ def crossrubyutils_sort_entries(ents)
114
+ ents.sort_by {|m| m_order(m) }
115
+ end
116
+
117
+ ORDER = { '.' => 1, '#' => 2, '::' => 3 }
118
+
119
+ def m_order(m)
120
+ m, t, c = *m.reverse.split(/(\#|\.|::)/, 2)
121
+ [ORDER[t] || 0, m.reverse]
122
+ end
123
+
124
+ def defined_methods(ruby, classname)
125
+ req = @requires.map {|lib| "-r#{lib}" }.join(' ')
126
+ avoid_tracer = ""
127
+ avoid_tracer = "Tracer.off" if @requires.include?("tracer")
128
+ if classname == 'Object'
129
+ `#{ruby} #{req} -e '
130
+ c = #{classname}
131
+ c.singleton_methods(false).each do |m|
132
+ puts "#{classname}.\#{m}"
133
+ end
134
+ c.instance_methods(true).each do |m|
135
+ puts "#{classname}\\#\#{m}"
136
+ end
137
+ '`.split
138
+ elsif classname == 'Kernel'
139
+ `#{ruby} #{req} -e '
140
+ c = #{classname}
141
+ c.singleton_methods(true).each do |m|
142
+ puts "#{classname}.\#{m}"
143
+ end
144
+ ( c.private_instance_methods(false) && c.methods(false) ).each do |m|
145
+ puts "#{classname}\\#\#{m}"
146
+ end
147
+ Object::constants.delete_if{|c| cl = Object.const_get(c).class; cl == Class or cl == Module }.each do |m|
148
+ puts "#{classname}::\#{m}"
149
+ end
150
+ global_variables.each do |m|
151
+ puts "#{classname}\#{m}"
152
+ end
153
+ '`.split
154
+ else
155
+ `#{ruby} #{req} -e '
156
+ #{avoid_tracer}
157
+ c = #{classname}
158
+ c.singleton_methods(false).each do |m|
159
+ puts "#{classname}.\#{m}"
160
+ end
161
+ c.instance_methods(false).each do |m|
162
+ puts "#{classname}\\#\#{m}"
163
+ end
164
+ c.ancestors.map {|mod| mod.constants }.inject {|r,n| r-n }.each do |m|
165
+ puts "#{classname}::\#{m}"
166
+ end
167
+ '`.split
168
+ end
169
+ end
170
+
171
+ main