From: Gabriel Horner Date: 2005-02-25T13:57:59+09:00 Subject: increasing ri's searching capibilities and some handy snippets Hi rubyheads, I'm new to the ruby community and am fascinated with its power,simplicity and clean syntax! Coming from the perl world where there never seemed to be a standard for documentation subroutines, I'm amazed with the ri command for providing such fine-grained searching of classes and their methods. Being a search freak, there are still more ways I'd like to be able to search ruby classes,files ,methods and variables. Since I got a lot of questions about rdoc/ri is this something I should take to the ruby-core mailing list? If so skip to question 2. 1. Extending ri search functions - Display code for a subroutine by extracting it from its file. I've seen this functionally in html form at http://www.ruby-doc.org/stdlib/ but I don't know how long it'll take to extract the relevant subroutines to do this from the commandline. - Display documentation for all instance methods of a class at once. I do this so I can quickly flip and search through to learn how to use a class. Currently this one-liner works for classes loaded by default. But it would be much handier if I knew how to map any class to its file (from rdoc generated info) to require the relevant file. ri `ruby -e 'print Object.const_get(ARGV[0].to_s).instance_methods(nil).sort.collect! {|x| ARGV[0]+"." +x }.join(" ")' Array` - See modules and classes and their methods defined by filename. See the sample ruby_file_parser.rb code I've pasted at the end of this email. -Backending ri's searching functions to a database for speed and flexibility in searching. Any such efforts to import 2. If I want to contribute handy snippets of code is the rubyforge.org snippet section the place to go? Doesn't seem that it gets much traffic. If I think some snippet is really handy and should come distributed with ruby in its sample/ directory who do I mention this to? For example, at the end there's a handy snippet, path.rb, I use daily to locate ruby files matching a given regular expression. Thanks, Gabriel ##path.rb require 'find' require 'optparse' OPT = { :verbose=>false, :gemdir=>false } def parseARGV ARGV.options do |opts| script_name = File.basename($0) opts.banner = "Usage: #{script_name} [options] search_term" opts.separator "" opts.on("-g",'--gemdir',"Include gemdir" ) {|OPT[:gemdir] |} opts.on("-v", "--verbose", "Verbose output","Default: false" ) { |OPT[:verbose] |} opts.on("-h", "--help", "Show this help message.") { puts opts; exit } opts.parse! end end files =[] parseARGV file = ARGV.shift or raise "No file given" GEMDIR = '/usr/local/lib/ruby/gems' #or generate with `gem environment gempath` searchdir = $: searchdir.push(GEMDIR) if OPT[:gemdir] searchdir.delete('.') i = 0 Find.find(*searchdir) do |f| puts "#{i}:#{f}" if OPT[:verbose] files.push(f) if f =~ /\/#{file}\.(so|rb)$/ i+=1 end puts files.uniq __END__ ##ruby_file_parser.rb require 'rdoc/options.rb' require 'rdoc/rdoc.rb' require 'rdoc/code_objects.rb' require 'rdoc/parsers/parse_rb.rb' require 'yaml' #redefined this subroutine cause the commented out section was throwing a bizarre '*' not defined error class RubyLex class BufferedReader def initialize(content) if /\t/ =~ content tab_width = Options.instance.tab_width #content = content.split(/\n/).map do |line| # 1 while line.gsub!(/\t+/) { ' ' * (tab_width*$&.length - $`.length % tab_width)} && $~ #` # line # end .join("\n") end @content = content @content << "\n" unless @content[-1,1] == "\n" @size = @content.size @offset = 0 @hwm = 0 @line_num = 1 @read_back_offset = 0 @last_newline = 0 @newline_pending = false end end end $final = {} def index_class(cls) class_name = cls.full_name $final[class_name] = cls.method_list.map {|x| x.name } if ! $final[class_name] cls.each_classmodule { |x| index_class(x) } end file = ARGV.shift or raise "no file given" content = File.open(file, "r") {|f| f.read} #P = RDoc::RubyParser.new(RDoc::TopLevel.new(file),file,content,Options.instance,RDoc::Stats.new) P = RDoc::ParserFactory.parser_for(RDoc::TopLevel.new(file),file,content,Options.instance,RDoc::Stats.new) P.scan rclasses = RDoc::TopLevel.all_classes_and_modules classes = rclasses.map {|x| x.full_name } for rc in rclasses index_class(rc) end puts YAML::dump($final) __END__ -- my looovely website -- http://www.chwhat.com BTW, IF chwhat.com goes down email me at gabriel.horner@cern.ch