rdoc 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rdoc might be problematic. Click here for more details.
- data.tar.gz.sig +1 -0
- data/History.txt +30 -0
- data/Manifest.txt +18 -6
- data/Rakefile +52 -0
- data/lib/rdoc.rb +69 -69
- data/lib/rdoc/code_objects.rb +331 -112
- data/lib/rdoc/generator.rb +172 -144
- data/lib/rdoc/generator/html.rb +45 -18
- data/lib/rdoc/generator/html/frameless.rb +795 -0
- data/lib/rdoc/generator/html/hefss.rb +11 -11
- data/lib/rdoc/generator/html/html.rb +81 -87
- data/lib/rdoc/generator/html/kilmer.rb +10 -10
- data/lib/rdoc/generator/html/one_page_html.rb +9 -9
- data/lib/rdoc/generator/ri.rb +5 -8
- data/lib/rdoc/generator/texinfo.rb +84 -0
- data/lib/rdoc/generator/texinfo/class.texinfo.erb +44 -0
- data/lib/rdoc/generator/texinfo/file.texinfo.erb +6 -0
- data/lib/rdoc/generator/texinfo/method.texinfo.erb +6 -0
- data/lib/rdoc/generator/texinfo/texinfo.erb +28 -0
- data/lib/rdoc/known_classes.rb +69 -0
- data/lib/rdoc/markup.rb +3 -3
- data/lib/rdoc/markup/attribute_manager.rb +0 -9
- data/lib/rdoc/markup/fragments.rb +1 -1
- data/lib/rdoc/markup/preprocess.rb +10 -6
- data/lib/rdoc/markup/to_html.rb +55 -8
- data/lib/rdoc/markup/to_html_crossref.rb +21 -5
- data/lib/rdoc/markup/to_texinfo.rb +69 -0
- data/lib/rdoc/options.rb +37 -14
- data/lib/rdoc/parser.rb +109 -0
- data/lib/rdoc/parser/c.rb +656 -0
- data/lib/rdoc/parser/f95.rb +1835 -0
- data/lib/rdoc/{parsers/parse_rb.rb → parser/ruby.rb} +1436 -1191
- data/lib/rdoc/parser/simple.rb +38 -0
- data/lib/rdoc/rdoc.rb +48 -32
- data/lib/rdoc/ri.rb +5 -1
- data/lib/rdoc/ri/descriptions.rb +8 -5
- data/lib/rdoc/ri/driver.rb +148 -49
- data/lib/rdoc/stats.rb +94 -4
- data/test/test_rdoc_info_formatting.rb +175 -0
- data/test/test_rdoc_info_sections.rb +136 -0
- data/test/test_rdoc_markup_to_html.rb +30 -0
- data/test/test_rdoc_markup_to_html_crossref.rb +18 -0
- data/test/{test_rdoc_c_parser.rb → test_rdoc_parser_c.rb} +8 -11
- data/test/test_rdoc_parser_ruby.rb +539 -0
- data/test/test_rdoc_ri_default_display.rb +17 -16
- data/test/test_rdoc_ri_driver.rb +92 -0
- metadata +54 -12
- metadata.gz.sig +0 -0
- data/lib/rdoc/parsers/parse_c.rb +0 -775
- data/lib/rdoc/parsers/parse_f95.rb +0 -1841
- data/lib/rdoc/parsers/parse_simple.rb +0 -40
- data/lib/rdoc/parsers/parserfactory.rb +0 -99
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rdoc/parser'
|
2
|
+
|
3
|
+
##
|
4
|
+
# Parse a non-source file. We basically take the whole thing as one big
|
5
|
+
# comment. If the first character in the file is '#', we strip leading pound
|
6
|
+
# signs.
|
7
|
+
|
8
|
+
class RDoc::Parser::Simple < RDoc::Parser
|
9
|
+
|
10
|
+
parse_files_matching(//)
|
11
|
+
|
12
|
+
##
|
13
|
+
# Prepare to parse a plain file
|
14
|
+
|
15
|
+
def initialize(top_level, file_name, content, options, stats)
|
16
|
+
super
|
17
|
+
|
18
|
+
preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include
|
19
|
+
|
20
|
+
preprocess.handle @content do |directive, param|
|
21
|
+
warn "Unrecognized directive '#{directive}' in #{@file_name}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Extract the file contents and attach them to the toplevel as a comment
|
27
|
+
|
28
|
+
def scan
|
29
|
+
@top_level.comment = remove_private_comments(@content)
|
30
|
+
@top_level
|
31
|
+
end
|
32
|
+
|
33
|
+
def remove_private_comments(comment)
|
34
|
+
comment.gsub(/^--[^-].*?^\+\+/m, '').sub(/^--.*/m, '')
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
data/lib/rdoc/rdoc.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
require 'rdoc'
|
2
2
|
|
3
|
-
require 'rdoc/
|
4
|
-
|
5
|
-
|
6
|
-
require 'rdoc/
|
3
|
+
require 'rdoc/parser'
|
4
|
+
|
5
|
+
# Simple must come first
|
6
|
+
require 'rdoc/parser/simple'
|
7
|
+
require 'rdoc/parser/ruby'
|
8
|
+
require 'rdoc/parser/c'
|
9
|
+
require 'rdoc/parser/f95'
|
7
10
|
|
8
11
|
require 'rdoc/stats'
|
9
12
|
require 'rdoc/options'
|
@@ -17,21 +20,24 @@ require 'time'
|
|
17
20
|
module RDoc
|
18
21
|
|
19
22
|
##
|
20
|
-
# Encapsulate the production of rdoc documentation. Basically
|
21
|
-
#
|
22
|
-
# line:
|
23
|
+
# Encapsulate the production of rdoc documentation. Basically you can use
|
24
|
+
# this as you would invoke rdoc from the command line:
|
23
25
|
#
|
24
|
-
#
|
25
|
-
#
|
26
|
+
# rdoc = RDoc::RDoc.new
|
27
|
+
# rdoc.document(args)
|
26
28
|
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
# for details.
|
29
|
+
# Where +args+ is an array of strings, each corresponding to an argument
|
30
|
+
# you'd give rdoc on the command line. See rdoc/rdoc.rb for details.
|
30
31
|
|
31
32
|
class RDoc
|
32
33
|
|
33
34
|
Generator = Struct.new(:file_name, :class_name, :key)
|
34
35
|
|
36
|
+
##
|
37
|
+
# Accessor for statistics. Available after each call to parse_files
|
38
|
+
|
39
|
+
attr_reader :stats
|
40
|
+
|
35
41
|
##
|
36
42
|
# This is the list of output generator that we support
|
37
43
|
|
@@ -54,7 +60,7 @@ module RDoc
|
|
54
60
|
end
|
55
61
|
|
56
62
|
def initialize
|
57
|
-
@stats =
|
63
|
+
@stats = nil
|
58
64
|
end
|
59
65
|
|
60
66
|
##
|
@@ -134,7 +140,7 @@ module RDoc
|
|
134
140
|
# subdirectories.
|
135
141
|
#
|
136
142
|
# The effect of this is that if you want a file with a non-standard
|
137
|
-
# extension parsed, you must name it
|
143
|
+
# extension parsed, you must name it explicitly.
|
138
144
|
|
139
145
|
def normalized_file_list(options, relative_files, force_doc = false,
|
140
146
|
exclude_pattern = nil)
|
@@ -146,7 +152,10 @@ module RDoc
|
|
146
152
|
case type = stat.ftype
|
147
153
|
when "file"
|
148
154
|
next if @last_created and stat.mtime < @last_created
|
149
|
-
|
155
|
+
|
156
|
+
if force_doc or ::RDoc::Parser.can_parse(rel_file_name) then
|
157
|
+
file_list << rel_file_name.sub(/^\.\//, '')
|
158
|
+
end
|
150
159
|
when "directory"
|
151
160
|
next if rel_file_name == "CVS" || rel_file_name == ".svn"
|
152
161
|
dot_doc = File.join(rel_file_name, DOT_DOC_FILENAME)
|
@@ -179,6 +188,8 @@ module RDoc
|
|
179
188
|
# Parse each file on the command line, recursively entering directories.
|
180
189
|
|
181
190
|
def parse_files(options)
|
191
|
+
@stats = Stats.new options.verbosity
|
192
|
+
|
182
193
|
files = options.files
|
183
194
|
files = ["."] if files.empty?
|
184
195
|
|
@@ -187,27 +198,30 @@ module RDoc
|
|
187
198
|
return [] if file_list.empty?
|
188
199
|
|
189
200
|
file_info = []
|
190
|
-
width = file_list.map { |name| name.length }.max + 1
|
191
201
|
|
192
|
-
file_list.each do |
|
193
|
-
|
202
|
+
file_list.each do |filename|
|
203
|
+
@stats.add_file filename
|
194
204
|
|
195
205
|
content = if RUBY_VERSION >= '1.9' then
|
196
|
-
File.open(
|
206
|
+
File.open(filename, "r:ascii-8bit") { |f| f.read }
|
197
207
|
else
|
198
|
-
File.read
|
208
|
+
File.read filename
|
199
209
|
end
|
200
210
|
|
201
|
-
if
|
202
|
-
if
|
203
|
-
|
211
|
+
if defined? Encoding then
|
212
|
+
if /coding:\s*(\S+)/ =~ content[/\A(?:.*\n){0,2}/]
|
213
|
+
if enc = ::Encoding.find($1)
|
214
|
+
content.force_encoding(enc)
|
215
|
+
end
|
204
216
|
end
|
205
217
|
end
|
206
218
|
|
207
|
-
top_level = TopLevel.new
|
208
|
-
|
219
|
+
top_level = ::RDoc::TopLevel.new filename
|
220
|
+
|
221
|
+
parser = ::RDoc::Parser.for top_level, filename, content, options,
|
222
|
+
@stats
|
223
|
+
|
209
224
|
file_info << parser.scan
|
210
|
-
@stats.num_files += 1
|
211
225
|
end
|
212
226
|
|
213
227
|
file_info
|
@@ -241,17 +255,19 @@ module RDoc
|
|
241
255
|
|
242
256
|
file_info = parse_files @options
|
243
257
|
|
258
|
+
@options.title = "RDoc Documentation"
|
259
|
+
|
244
260
|
if file_info.empty?
|
245
261
|
$stderr.puts "\nNo newer files." unless @options.quiet
|
246
262
|
else
|
247
|
-
gen = @options.generator
|
263
|
+
@gen = @options.generator
|
248
264
|
|
249
|
-
$stderr.puts "\nGenerating #{gen.key.upcase}..." unless @options.quiet
|
265
|
+
$stderr.puts "\nGenerating #{@gen.key.upcase}..." unless @options.quiet
|
250
266
|
|
251
|
-
require gen.file_name
|
267
|
+
require @gen.file_name
|
252
268
|
|
253
|
-
gen_class = ::RDoc::Generator.const_get gen.class_name
|
254
|
-
gen = gen_class.for @options
|
269
|
+
gen_class = ::RDoc::Generator.const_get @gen.class_name
|
270
|
+
@gen = gen_class.for @options
|
255
271
|
|
256
272
|
pwd = Dir.pwd
|
257
273
|
|
@@ -259,7 +275,7 @@ module RDoc
|
|
259
275
|
|
260
276
|
begin
|
261
277
|
Diagram.new(file_info, @options).draw if @options.diagram
|
262
|
-
gen.generate(file_info)
|
278
|
+
@gen.generate(file_info)
|
263
279
|
update_output_dir(".", start_time)
|
264
280
|
ensure
|
265
281
|
Dir.chdir(pwd)
|
data/lib/rdoc/ri.rb
CHANGED
data/lib/rdoc/ri/descriptions.rb
CHANGED
@@ -2,11 +2,10 @@ require 'yaml'
|
|
2
2
|
require 'rdoc/markup/fragments'
|
3
3
|
require 'rdoc/ri'
|
4
4
|
|
5
|
-
|
5
|
+
##
|
6
6
|
# Descriptions are created by RDoc (in ri_generator) and written out in
|
7
7
|
# serialized form into the documentation tree. ri then reads these to generate
|
8
8
|
# the documentation
|
9
|
-
#++
|
10
9
|
|
11
10
|
class RDoc::RI::NamedThing
|
12
11
|
attr_reader :name
|
@@ -83,7 +82,7 @@ class RDoc::RI::ModuleDescription < RDoc::RI::Description
|
|
83
82
|
attr_accessor :constants
|
84
83
|
attr_accessor :includes
|
85
84
|
|
86
|
-
# merge in another class
|
85
|
+
# merge in another class description into this one
|
87
86
|
def merge_in(old)
|
88
87
|
merge(@class_methods, old.class_methods)
|
89
88
|
merge(@instance_methods, old.instance_methods)
|
@@ -94,8 +93,12 @@ class RDoc::RI::ModuleDescription < RDoc::RI::Description
|
|
94
93
|
@comment = old.comment
|
95
94
|
else
|
96
95
|
unless old.comment.nil? or old.comment.empty? then
|
97
|
-
@comment
|
98
|
-
|
96
|
+
if @comment.nil? or @comment.empty? then
|
97
|
+
@comment = old.comment
|
98
|
+
else
|
99
|
+
@comment << RDoc::Markup::Flow::RULE.new
|
100
|
+
@comment.concat old.comment
|
101
|
+
end
|
99
102
|
end
|
100
103
|
end
|
101
104
|
end
|
data/lib/rdoc/ri/driver.rb
CHANGED
@@ -11,6 +11,64 @@ require 'rdoc/markup/to_flow'
|
|
11
11
|
|
12
12
|
class RDoc::RI::Driver
|
13
13
|
|
14
|
+
class Hash < ::Hash
|
15
|
+
def self.convert(hash)
|
16
|
+
hash = new.update hash
|
17
|
+
|
18
|
+
hash.each do |key, value|
|
19
|
+
hash[key] = case value
|
20
|
+
when ::Hash then
|
21
|
+
convert value
|
22
|
+
when Array then
|
23
|
+
value = value.map do |v|
|
24
|
+
::Hash === v ? convert(v) : v
|
25
|
+
end
|
26
|
+
value
|
27
|
+
else
|
28
|
+
value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
hash
|
33
|
+
end
|
34
|
+
|
35
|
+
def method_missing method, *args
|
36
|
+
self[method.to_s]
|
37
|
+
end
|
38
|
+
|
39
|
+
def merge_enums(other)
|
40
|
+
other.each do |k, v|
|
41
|
+
if self[k] then
|
42
|
+
case v
|
43
|
+
when Array then
|
44
|
+
# HACK dunno
|
45
|
+
if String === self[k] and self[k].empty? then
|
46
|
+
self[k] = v
|
47
|
+
else
|
48
|
+
self[k] += v
|
49
|
+
end
|
50
|
+
when Hash then
|
51
|
+
self[k].update v
|
52
|
+
else
|
53
|
+
# do nothing
|
54
|
+
end
|
55
|
+
else
|
56
|
+
self[k] = v
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Error < RDoc::RI::Error; end
|
63
|
+
|
64
|
+
class NotFoundError < Error
|
65
|
+
def message
|
66
|
+
"Nothing known about #{super}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
attr_accessor :homepath # :nodoc:
|
71
|
+
|
14
72
|
def self.process_args(argv)
|
15
73
|
options = {}
|
16
74
|
options[:use_stdout] = !$stdout.tty?
|
@@ -234,7 +292,7 @@ Options may also be set in the 'RI' environment variable.
|
|
234
292
|
@class_cache = if up_to_date then
|
235
293
|
load_cache_for @class_cache_name
|
236
294
|
else
|
237
|
-
class_cache =
|
295
|
+
class_cache = RDoc::RI::Driver::Hash.new
|
238
296
|
|
239
297
|
classes = map_dirs('**/cdesc*.yaml', :sys) { |f| Dir[f] }
|
240
298
|
populate_class_cache class_cache, classes
|
@@ -245,6 +303,9 @@ Options may also be set in the 'RI' environment variable.
|
|
245
303
|
populate_class_cache class_cache, classes, true
|
246
304
|
write_cache class_cache, class_cache_file_path
|
247
305
|
end
|
306
|
+
|
307
|
+
@class_cache = RDoc::RI::Driver::Hash.convert @class_cache
|
308
|
+
@class_cache
|
248
309
|
end
|
249
310
|
|
250
311
|
def class_cache_file_path
|
@@ -261,21 +322,29 @@ Options may also be set in the 'RI' environment variable.
|
|
261
322
|
|
262
323
|
def display_class(name)
|
263
324
|
klass = class_cache[name]
|
325
|
+
klass = RDoc::RI::Driver::Hash.convert klass
|
264
326
|
@display.display_class_info klass, class_cache
|
265
327
|
end
|
266
328
|
|
329
|
+
def get_info_for(arg)
|
330
|
+
@names = [arg]
|
331
|
+
run
|
332
|
+
end
|
333
|
+
|
267
334
|
def load_cache_for(klassname)
|
268
335
|
path = cache_file_for klassname
|
269
336
|
|
337
|
+
cache = nil
|
338
|
+
|
270
339
|
if File.exist? path and
|
271
340
|
File.mtime(path) >= File.mtime(class_cache_file_path) then
|
272
|
-
|
273
|
-
Marshal.load fp.read
|
341
|
+
open path, 'rb' do |fp|
|
342
|
+
cache = Marshal.load fp.read
|
274
343
|
end
|
275
344
|
else
|
276
345
|
class_cache = nil
|
277
346
|
|
278
|
-
|
347
|
+
open class_cache_file_path, 'rb' do |fp|
|
279
348
|
class_cache = Marshal.load fp.read
|
280
349
|
end
|
281
350
|
|
@@ -283,7 +352,7 @@ Options may also be set in the 'RI' environment variable.
|
|
283
352
|
return nil unless klass
|
284
353
|
|
285
354
|
method_files = klass["sources"]
|
286
|
-
cache =
|
355
|
+
cache = RDoc::RI::Driver::Hash.new
|
287
356
|
|
288
357
|
sys_dir = @sys_dirs.first
|
289
358
|
method_files.each do |f|
|
@@ -296,12 +365,45 @@ Options may also be set in the 'RI' environment variable.
|
|
296
365
|
ext_path = f
|
297
366
|
ext_path = "gem #{$1}" if f =~ %r%gems/[\d.]+/doc/([^/]+)%
|
298
367
|
method["source_path"] = ext_path unless system_file
|
299
|
-
cache[name] = method
|
368
|
+
cache[name] = RDoc::RI::Driver::Hash.convert method
|
300
369
|
end
|
301
370
|
end
|
302
371
|
|
303
372
|
write_cache cache, path
|
304
373
|
end
|
374
|
+
|
375
|
+
RDoc::RI::Driver::Hash.convert cache
|
376
|
+
end
|
377
|
+
|
378
|
+
##
|
379
|
+
# Finds the next ancestor of +orig_klass+ after +klass+.
|
380
|
+
|
381
|
+
def lookup_ancestor(klass, orig_klass)
|
382
|
+
cache = class_cache[orig_klass]
|
383
|
+
|
384
|
+
return nil unless cache
|
385
|
+
|
386
|
+
ancestors = [orig_klass]
|
387
|
+
ancestors.push(*cache.includes.map { |inc| inc['name'] })
|
388
|
+
ancestors << cache.superclass
|
389
|
+
|
390
|
+
ancestor = ancestors[ancestors.index(klass) + 1]
|
391
|
+
|
392
|
+
return ancestor if ancestor
|
393
|
+
|
394
|
+
lookup_ancestor klass, cache.superclass
|
395
|
+
end
|
396
|
+
|
397
|
+
##
|
398
|
+
# Finds the method
|
399
|
+
|
400
|
+
def lookup_method(name, klass)
|
401
|
+
cache = load_cache_for klass
|
402
|
+
return nil unless cache
|
403
|
+
|
404
|
+
method = cache[name.gsub('.', '#')]
|
405
|
+
method = cache[name.gsub('.', '::')] unless method
|
406
|
+
method
|
305
407
|
end
|
306
408
|
|
307
409
|
def map_dirs(file_name, system=false)
|
@@ -318,6 +420,22 @@ Options may also be set in the 'RI' environment variable.
|
|
318
420
|
dirs.map { |dir| yield File.join(dir, file_name) }.flatten.compact
|
319
421
|
end
|
320
422
|
|
423
|
+
##
|
424
|
+
# Extract the class and method name parts from +name+ like Foo::Bar#baz
|
425
|
+
|
426
|
+
def parse_name(name)
|
427
|
+
parts = name.split(/(::|\#|\.)/)
|
428
|
+
|
429
|
+
if parts[-2] != '::' or parts.last !~ /^[A-Z]/ then
|
430
|
+
meth = parts.pop
|
431
|
+
parts.pop
|
432
|
+
end
|
433
|
+
|
434
|
+
klass = parts.join
|
435
|
+
|
436
|
+
[klass, meth]
|
437
|
+
end
|
438
|
+
|
321
439
|
def populate_class_cache(class_cache, classes, extension = false)
|
322
440
|
classes.each do |cdesc|
|
323
441
|
desc = read_yaml cdesc
|
@@ -337,6 +455,8 @@ Options may also be set in the 'RI' environment variable.
|
|
337
455
|
desc["class_method_extensions"] = desc.delete "class_methods"
|
338
456
|
end
|
339
457
|
|
458
|
+
klass = RDoc::RI::Driver::Hash.convert klass
|
459
|
+
|
340
460
|
klass.merge_enums desc
|
341
461
|
klass["sources"] << cdesc
|
342
462
|
end
|
@@ -351,11 +471,6 @@ Options may also be set in the 'RI' environment variable.
|
|
351
471
|
YAML.load data
|
352
472
|
end
|
353
473
|
|
354
|
-
def get_info_for(arg)
|
355
|
-
@names = [arg]
|
356
|
-
run
|
357
|
-
end
|
358
|
-
|
359
474
|
def run
|
360
475
|
if @names.empty? then
|
361
476
|
@display.list_known_classes class_cache.keys.sort
|
@@ -366,17 +481,26 @@ Options may also be set in the 'RI' environment variable.
|
|
366
481
|
if class_cache.key? name then
|
367
482
|
display_class name
|
368
483
|
else
|
369
|
-
|
484
|
+
klass, = parse_name name
|
485
|
+
|
486
|
+
orig_klass = klass
|
487
|
+
orig_name = name
|
488
|
+
|
489
|
+
until klass == 'Kernel' do
|
490
|
+
method = lookup_method name, klass
|
370
491
|
|
371
|
-
|
372
|
-
|
373
|
-
|
492
|
+
break method if method
|
493
|
+
|
494
|
+
ancestor = lookup_ancestor klass, orig_klass
|
495
|
+
|
496
|
+
break unless ancestor
|
497
|
+
|
498
|
+
name = name.sub klass, ancestor
|
499
|
+
klass = ancestor
|
500
|
+
end
|
501
|
+
|
502
|
+
raise NotFoundError, orig_name unless method
|
374
503
|
|
375
|
-
cache = load_cache_for klass
|
376
|
-
# HACK Does not support F.n
|
377
|
-
abort "Nothing known about #{name}" unless cache
|
378
|
-
method = cache[name.gsub(/\./, '#')]
|
379
|
-
abort "Nothing known about #{name}" unless method
|
380
504
|
@display.display_method_info method
|
381
505
|
end
|
382
506
|
else
|
@@ -384,8 +508,9 @@ Options may also be set in the 'RI' environment variable.
|
|
384
508
|
display_class name
|
385
509
|
else
|
386
510
|
methods = select_methods(/^#{name}/)
|
511
|
+
|
387
512
|
if methods.size == 0
|
388
|
-
|
513
|
+
raise NotFoundError, name
|
389
514
|
elsif methods.size == 1
|
390
515
|
@display.display_method_info methods.first
|
391
516
|
else
|
@@ -395,6 +520,8 @@ Options may also be set in the 'RI' environment variable.
|
|
395
520
|
end
|
396
521
|
end
|
397
522
|
end
|
523
|
+
rescue NotFoundError => e
|
524
|
+
abort e.message
|
398
525
|
end
|
399
526
|
|
400
527
|
def select_methods(pattern)
|
@@ -422,31 +549,3 @@ Options may also be set in the 'RI' environment variable.
|
|
422
549
|
|
423
550
|
end
|
424
551
|
|
425
|
-
class Hash # HACK don't add stuff to Hash.
|
426
|
-
def method_missing method, *args
|
427
|
-
self[method.to_s]
|
428
|
-
end
|
429
|
-
|
430
|
-
def merge_enums(other)
|
431
|
-
other.each do |k,v|
|
432
|
-
if self[k] then
|
433
|
-
case v
|
434
|
-
when Array then
|
435
|
-
# HACK dunno
|
436
|
-
if String === self[k] and self[k].empty? then
|
437
|
-
self[k] = v
|
438
|
-
else
|
439
|
-
self[k] += v
|
440
|
-
end
|
441
|
-
when Hash then
|
442
|
-
self[k].merge! v
|
443
|
-
else
|
444
|
-
# do nothing
|
445
|
-
end
|
446
|
-
else
|
447
|
-
self[k] = v
|
448
|
-
end
|
449
|
-
end
|
450
|
-
end
|
451
|
-
end
|
452
|
-
|