On Fri, 19 Jan 2007 22:45:05 +0900, Ruby Quiz 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 Returning an array when the answer is ambiguous is a very bad way to do this. Instead, I throw an exception (you can get the candidates from the #candidates attribute of the exception). I also saw no reason to specifically name the methods that get abbreviated -- rather, abbreviation works on all methods in the object and its super classes. require 'abbrev' class AmbiguousExpansionError < StandardError attr_accessor :candidates def initialize(name,possible_methods) super("Ambiguous abbreviaton: #{name}\n"+ "Candidates: #{possible_methods.join(", ")}") @candidates=possible_methods end end module Abbreviator def method_missing name,*args abbrevs=methods.abbrev return send(abbrevs[name.to_s],*args) if abbrevs[name.to_s] meths=abbrevs.reject{|key,value| key!~/^#{name}/}.values.uniq raise AmbiguousExpansionError.new(name, meths) if meths.length>1 return super(name,*args) end end -- Ken Bloom. PhD candidate. Linguistic Cognition Laboratory. Department of Computer Science. Illinois Institute of Technology. http://www.iit.edu/~kbloom1/