Last week I was kind of embarrassed that Bob chose to feature my late,
poorly commented, somewhat opaque solution, but I certainly appreciate
the inclusive spirit of Ruby Quiz. Here's a more timely submission for
the auto completion problem.

--------------------------------------------------------
class Object
  def self.abbrev(*args)
    module_eval <<-EOS
    @@abbrevs ||= []
    @@abbrevs += args

    def method_missing(m)
      # abbrev targets themselves are not supposed to be expanded
      raise NoMethodError if @@abbrevs.include?(m)

      # which abbrev targets could match m, and which of those
correspond to methods?
      matches = @@abbrevs.select do |sym|
        sym.to_s.index(m.to_s) == 0 && methods.include?(sym.to_s)
      end

      case matches.size
        when 0
          raise NoMethodError
        when 1
          self.send(matches.first)
        else
          # multiple matches, pass them back to the user
          return matches if $TESTING
          puts matches.join(" ")
      end
    end
    EOS

  end
end
--------------------------------------------------------

This code passes the supplied tests, and I also added another test
when an earlier version of my code was doing things it shouldn't have:

--------------------------------------------------------
# check for unintended effects on other classes
class Test3 < Test::Unit::TestCase
  def setup
    @foo_class = Class.new {
      abbrev :start
      def start; nil end
    }
    @bar_class = Class.new {
      def start; nil end
    }
  end

  def test1
    f = @foo_class.new
    b = @bar_class.new
    assert_raise NoMethodError do
       b.send(:sta)
    end
  end
end
--------------------------------------------------------


I don't feel very confident in the approach I've taken, so I'm eager
to hear critique and see other solutions.

Krishna



On 1/19/07, Ruby Quiz <james / grayproductions.net> wrote:
> The three rules of Ruby Quiz:
>
> 1.  Please do not post any solutions or spoiler discussion for this quiz until
> 48 hours have passed from the time on this message.
>
> 2.  Support Ruby Quiz by submitting ideas as often as you can:
>
> http://www.rubyquiz.com/
>
> 3.  Enjoy!
>
> Suggestion:  A [QUIZ] in the subject of emails about the problem helps everyone
> on Ruby Talk follow the discussion.  Please reply to the original quiz message,
> if you can.
>
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
>
> by Robert Dober
>
> Command Line Interfaces very often support command abbreviations The purpose of
> this quiz is to automatically dispatch to methods on unambiguous abbreviations,
> ask the user for clarification in case of ambiguous abbreviations and raise a
> NoMethodError in case of an abbreviation that cannot be matched to any command.
>
> Behavior of other methods defined in a class shall not be altered.
>
> Be creative about the interface and about behavior. I have OTOH defined a small
> test suite that makes assumptions about the interface and behavior. But the test
> suite is only there for your convenience.
>
> What is said below applies to the test suite and shall in no way inhibit any
> alternative ideas.
>
>         class Mine
>           abbrev :step, :next, :stop
>           abbrev :exit
>         end
>
>         Mine.new.e  # should resolve to exit
>         Mine.new.st # should prompt the user
>         Mine.new.a  # should still raise a NoMethodError
>
> Abbreviation targets themselves are not expanded.
>
>         class Nine
>           abbrev  :hash
>           abbrev  :has
>         end
>
>         Nine.new.ha  # => [:hash, :has]
>         Nine.new.has # => NoMethodError
>
>         class Nine
>           def has; 42; end
>         end
>         Nine.new.has # => 42
>
> In order to allow for automated testing the test code shall not prompt the user
> in case of an ambiguous abbreviation but return an array containing all (and
> only all) possible completions as symbols. Note that the test suite sets the
> global variable $TESTING to a true value for your convenience.
>
>         http://rubyquiz.com/test-abbrev.rb
>
>