Dear Dave,

Thanks a lot for 'ri'; its *very* useful. I patched my ri script so
that it can handle prefix matches. You'll find the patch below in case
someone else finds it useful.

With this patch you can do

ri Ar                 same as        ri Array
ri Ar#collect         same as        ri Array#collect
ri Di#chd             same as        ri Dir#chdir

etc. and also

$ ri Bi
Multiple classes have same prefix as `Bi':
     Bignum, Binding

$ ri ea
No method named `ea' but several methods have same prefix:
     each_object, each_key, each, each_pair, each_line, each_index,
     each_with_index, each_byte, each_value

$ ri Ar#co
Multiple methods have same prefix as `co':
     collect, collect!, compact, compact!, concat

$ ./ri ear
No method named `ear' but several methods have same prefix:
     each_object, each_key, each, each_pair, each_line, each_index,
     each_with_index, each_byte, each_value

No doubt, the patch can be refactored and made more "beautiful". Some 
"bugs" are in there if you specify more than 1 thing to look up at the 
same time. Probably some other ones too ;-)...

Regards,

Robert

--- ri.old	Mon Feb 26 13:38:36 2001
+++ ri	Mon Feb 26 14:05:38 2001
@@ -50,18 +50,68 @@
 end
 
 ##
+# Filter out strings in array with given prefix. If none match and
+# recurseWhileShrinking then drop char's at the end of prefix and try
again.
+#
+def filter_strings_with_prefix(anArrayOfStrings, prefix, 
+			       recurseWhileShrinking = true)
+  return [] unless prefix.length > 0
+  res = anArrayOfStrings.collect {|s| ((s =~ prefix) == 0) ? s
: nil}.compact
+  return res if res.length > 0
+  if recurseWhileShrinking
+    filter_strings_with_prefix(anArrayOfStrings, prefix[0...-1], true)
+  else
+    []
+  end
+end
+
+def classes
+  classes = nil
+  Dir.open($datadir) {|dir| classes = dir.grep(/^[A-Z]/)}
+  classes
+end
+
+##
 # Read in a serialized class description
 #
 def findClass(name)
   fname = name.tr(':', '_')
   begin
     File.open(File.join($datadir, fname)) do |f|
-      return Marshal.load(f)
+      cl = Marshal.load(f)
+      def cl.findMethod(meth, classMethod)
+	@methods.each do |m|
+	  if m.name == meth
+	    return m if classMethod and m.type == "class"
+	    return m if !classMethod and m.type != "class"
+	  end
+	end
+	methods = 
+	  filter_strings_with_prefix(@methods.collect{|m| m.name}, meth)
+	if methods.length > 1
+	  $stderr.puts "Multiple methods have same prefix as `#{meth}':\n"
+	  $stderr.puts Text::wrap("     ", methods.join(", "))
+	  exit(1)
+	else
+	  @methods.detect{|m| m.name == methods[0]}
+	end
+      end
+      return cl 
     end
   rescue
-    $stderr.puts "Couldn't find class/module `#{name}'.\n" +
+    classes_with_prefix = filter_strings_with_prefix(classes, name)
+    if classes_with_prefix.length == 1
+      fname = classes_with_prefix.first
+      retry
+    elsif classes_with_prefix.length > 1
+      $stderr.puts "Multiple classes have same prefix as `#{name}':\n"
+      $stderr.puts Text::wrap("     ", classes_with_prefix.join(", "))
+      exit(1)
+    else
+      $stderr.puts "Couldn't find class/module `#{name}'.\n" +
       "Use #$0 with no parameter for a list"
-    exit(1)
+      exit(1)
+    end
   end
 end
 
@@ -83,7 +133,6 @@
   end
 end
 
-
 ##
 # Print a simple list of classes and exit
 def usage
@@ -92,14 +141,12 @@
   $stderr.puts "\nDisplays documentation for the names classes or
methods\n\n"
   $stderr.puts "I have documentation for the classes and modules:\n\n"
 
-  Dir.open($datadir) do |dir|
-    names = dir.grep(/^[A-Z]/)
+  names = classes
 
-    if names.size.zero?
-      $stderr.puts "Configuration error: could not find class list"
-    else
-      puts Text::wrap("     ", names.sort.join(", "))
-    end
+  if names.size.zero?
+    $stderr.puts "Configuration error: could not find class list"
+  else
+    puts Text::wrap("     ", names.sort.join(", "))
   end
 end
 
@@ -170,8 +217,20 @@
   options = index[name]
 
   if !options
-    $stderr.puts "Don't know anything about a method called `#{name}'."
-    exit(1)
+    def index.method_with_prefix(name)
+      filter_strings_with_prefix(@index.keys, name, true)
+    end
+    methods = index.method_with_prefix(name)
+    if methods.length == 0
+      $stderr.puts "Don't know anything about a method called `#{name}'."
+      exit(1)
+    elsif methods.length > 1
+      puts "No method named `#{name}' but several methods have same
prefix:"
+      puts Text::wrap("     ", methods.join(", "))
+      exit(0)
+    else
+      options = index[methods[0]]
+    end
   end
 
   if options.size == 1