今天在Ruby上装了Win32API的Gem,想在fxri中看一下有哪些模块,却发现列表里没有出现,网上找了半天也没找到原因。最后花了2个小时看了fxri、ri和RubyGems的源码,终于找到了原因。
新的RubyGems在返回Gem.path给的是一个数组,而ri中认为Gem.path是一个字符串而生成了一个不存在的搜索路径,因此找不到Gem的Doc。
因此我修改了ri中的代码,使其支持新版RubyGems的Gem.path方法。
文件名:ri_paths.rb
原始代码:
- GEMDIRS = Dir["#{Gem.path}/doc/*/ri"]
- GEMDIRS.each { |path| RI::Paths::PATH << path }
修改好的代码:
- GEMDIRS = Gem.path.dup
- GEMDIRS.length.times{ |n|
- GEMDIRS[n] = Dir["#{GEMDIRS[n]}/doc/*/ri"]
- GEMDIRS[n].each { |path| RI::Paths::PATH << path }
- }
文件名:ri_options.rb
原始代码:
第一部分:
- (RI::Paths::GEMDIRS ? "#{Gem.path}/doc/*/ri" :
- No Rubygems ri found.") ],
第二部分:
- directories << "#{Gem.path}/doc/*/ri" if RI::Paths::GEMDIRS
修改好的代码:
第一部分:
- (RI::Paths::GEMDIRS ? "#{Gem.path.inject(""){ |strall,strpath| strall += strpath + "/n "} }":
- "No Rubygems ri found.") ],
第二部分:
- Gem.path.each{ |path| directories << "#{path}/doc/*/ri" if RI::Paths::GEMDIRS}
修改好的完整文件如下:
文件下载地址:http://download.csdn.net/source/929228
ri_paths.rb
- module RI
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- module Paths
-
- require 'rbconfig'
-
- DOC_DIR = "doc/rdoc"
- version = Config::CONFIG['ruby_version']
- base = File.join(Config::CONFIG['datadir'], "ri", version)
- SYSDIR = File.join(base, "system")
- SITEDIR = File.join(base, "site")
- homedir = ENV['HOME'] || ENV['USERPROFILE'] || ENV['HOMEPATH']
- if homedir
- HOMEDIR = File.join(homedir, ".rdoc")
- else
- HOMEDIR = nil
- end
-
- PATH = [ SYSDIR, SITEDIR, HOMEDIR ].find_all {|p| p && File.directory?(p)}
- begin
- require 'rubygems'
-
-
-
- GEMDIRS = Gem.path.dup
- GEMDIRS.length.times{ |n|
- GEMDIRS[n] = Dir["#{GEMDIRS[n]}/doc/*/ri"]
- GEMDIRS[n].each { |path| RI::Paths::PATH << path }
- }
- rescue LoadError
- GEMDIRS = nil
- end
-
-
- def self.path(use_system, use_site, use_home, use_gems, *extra_dirs)
- path = raw_path(use_system, use_site, use_home, use_gems, *extra_dirs)
- return path.select { |path| File.directory? path }
- end
-
-
-
- def self.raw_path(use_system, use_site, use_home, use_gems, *extra_dirs)
- return PATH unless use_system or use_site or use_home or use_gems or
- not extra_dirs.empty?
- path = []
- path << extra_dirs unless extra_dirs.empty?
- path << RI::Paths::SYSDIR if use_system
- path << RI::Paths::SITEDIR if use_site
- path << RI::Paths::HOMEDIR if use_home
- path << RI::Paths::GEMDIRS if use_gems
- return path.flatten.compact
- end
- end
- end
ri_options.rb文件
- module RI
- require 'rdoc/ri/ri_paths'
- require 'rdoc/ri/ri_display'
- VERSION_STRING = "ri v1.0.1 - 20041108"
- class Options
-
- require 'singleton'
- require 'getoptlong'
-
- include Singleton
-
-
- attr_accessor :use_stdout
-
- attr_reader :list_classes
-
- attr_reader :list_names
-
- attr_reader :width
-
- attr_reader :formatter
-
- attr_reader :doc_dir
- module OptionList
-
- OPTION_LIST = [
- [ "--help", "-h", nil,
- "you're looking at it" ],
- [ "--classes", "-c", nil,
- "Display the names of classes and modules we/n" +
- "know about"],
- [ "--doc-dir", "-d", "<dirname>",
- "A directory to search for documentation. If not/n" +
- "specified, we search the standard rdoc/ri directories./n" +
- "May be repeated."],
- [ "--system", nil, nil,
- "Include documentation from Ruby's standard library:/n " +
- RI::Paths::SYSDIR ],
- [ "--site", nil, nil,
- "Include documentation from libraries installed in site_lib:/n " +
- RI::Paths::SITEDIR ],
- [ "--home", nil, nil,
- "Include documentation stored in ~/.rdoc:/n " +
- (RI::Paths::HOMEDIR || "No ~/.rdoc found") ],
- [ "--gems", nil, nil,
- "Include documentation from Rubygems:/n " +
- (RI::Paths::GEMDIRS ? "#{Gem.path.inject(""){ |strall,strpath| strall += strpath + "/n "} }":
- "No Rubygems ri found.") ],
-
- [ "--format", "-f", "<name>",
- "Format to use when displaying output:/n" +
- " " + RI::TextFormatter.list + "/n" +
- "Use 'bs' (backspace) with most pager programs./n" +
- "To use ANSI, either also use the -T option, or/n" +
- "tell your pager to allow control characters/n" +
- "(for example using the -R option to less)"],
- [ "--list-names", "-l", nil,
- "List all the names known to RDoc, one per line"
- ],
- [ "--no-pager", "-T", nil,
- "Send output directly to stdout."
- ],
- [ "--width", "-w", "output width",
- "Set the width of the output" ],
- [ "--version", "-v", nil,
- "Display the version of ri"
- ],
- ]
- def OptionList.options
- OPTION_LIST.map do |long, short, arg,|
- option = []
- option << long
- option << short unless short.nil?
- option << (arg ? GetoptLong::REQUIRED_ARGUMENT :
- GetoptLong::NO_ARGUMENT)
- option
- end
- end
- def OptionList.strip_output(text)
- text =~ /^/s+/
- leading_spaces = $
- text.gsub!(/^
- $stdout.puts text
- end
-
-
-
-
- def OptionList.error(msg)
- $stderr.puts
- $stderr.puts msg
- $stderr.puts "/nFor help on options, try 'ri --help'/n/n"
- exit 1
- end
-
-
-
- def OptionList.usage(short_form=false)
-
- puts
- puts(RI::VERSION_STRING)
- puts
-
- name = File.basename($0)
- directories = [
- RI::Paths::SYSDIR,
- RI::Paths::SITEDIR,
- RI::Paths::HOMEDIR
- ]
- Gem.path.each{ |path| directories << "#{path}/doc/*/ri" if RI::Paths::GEMDIRS}
- directories = directories.join("/n ")
- OptionList.strip_output(<<-EOT)
- Usage:
-
- Display information on Ruby classes, modules, and methods.
- Give the names of classes or methods to see their documentation.
- Partial names may be given: if the names match more than
- one entity, a list will be shown, otherwise details on
- that entity will be displayed.
- Nested classes and modules can be specified using the normal
- Name::Name notation, and instance methods can be distinguished
- from class methods using "." (or "#") instead of "::".
- For example:
- ri File
- ri File.new
- ri F.n
- ri zip
- Note that shell quoting may be required for method names
- containing punctuation:
- ri 'Array.[]'
- ri compact//!
- By default ri searches for documentation in the following
- directories:
-
- Specifying the --system, --site, --home, --gems or --doc-dir
- options will limit ri to searching only the specified
- directories.
- EOT
- if short_form
- puts "For help on options, type 'ri -h'"
- puts "For a list of classes I know about, type 'ri -c'"
- else
- puts "Options:/n/n"
- OPTION_LIST.each do|long, short, arg, desc|
- opt = ''
- opt << (short ? sprintf("%15s", "#{long}, #{short}") :
- sprintf("%15s", long))
- if arg
- opt << " " << arg
- end
- print opt
- desc = desc.split("/n")
- if opt.size < 17
- print " "*(18-opt.size)
- puts desc.shift
- else
- puts
- end
- desc.each do |line|
- puts(" "*18 + line)
- end
- puts
- end
- puts "Options may also be passed in the 'RI' environment variable"
- exit 0
- end
- end
- end
-
- def show_version
- puts VERSION_STRING
- exit(0)
- end
- def initialize
- @use_stdout = !STDOUT.tty?
- @width = 72
- @formatter = RI::TextFormatter.for("plain")
- @list_classes = false
- @list_names = false
-
-
- @use_system = false
- @use_site = false
- @use_home = false
- @use_gems = false
- @doc_dirs = []
- end
-
- def parse(args)
-
- old_argv = ARGV.dup
- ARGV.replace(args)
- begin
- go = GetoptLong.new(*OptionList.options)
- go.quiet = true
- go.each do |opt, arg|
- case opt
- when "--help" then OptionList.usage
- when "--version" then show_version
- when "--list-names" then @list_names = true
- when "--no-pager" then @use_stdout = true
- when "--classes" then @list_classes = true
- when "--system" then @use_system = true
- when "--site" then @use_site = true
- when "--home" then @use_home = true
- when "--gems" then @use_gems = true
- when "--doc-dir"
- if File.directory?(arg)
- @doc_dirs << arg
- else
- $stderr.puts "Invalid directory: #{arg}"
- exit 1
- end
- when "--format"
- @formatter = RI::TextFormatter.for(arg)
- unless @formatter
- $stderr.print "Invalid formatter (should be one of "
- $stderr.puts RI::TextFormatter.list + ")"
- exit 1
- end
- when "--width"
- begin
- @width = Integer(arg)
- rescue
- $stderr.puts "Invalid width: '#{arg}'"
- exit 1
- end
- end
- end
- rescue GetoptLong::InvalidOption, GetoptLong::MissingArgument => error
- OptionList.error(error.message)
- end
- end
-
- def path
- RI::Paths.path(@use_system, @use_site, @use_home, @use_gems, *@doc_dirs)
- end
- def raw_path
- RI::Paths.raw_path(@use_system, @use_site, @use_home, @use_gems,
- *@doc_dirs)
- end
-
-
-
-
- def displayer
- ::RiDisplay.new(self)
- end
- end
- end