From: Jamie Macey Date: 2006-11-27T13:40:31+09:00 Subject: Re: [QUIZ] DictionaryMatcher (#103) Well, I'm not sure I can add anything not covered by Adam's solution (forwarded in by James), but here goes. I started with the naive solution: class DictionaryMatcher < Array def =~(string) self.map{|e| Regexp.new(e) =~ string }.compact.min end end I then fleshed it out with a case insensitive option, and more tests. - Jamie class DictionaryMatcher < Array alias_method :===, :=~ alias_method :match, :=~ def initialize(default = [], options = nil) super(default) unless options.nil? or options.is_a? Fixnum options = Regexp::IGNORECASE end @regexp_options = options end def =~(string) self.map{|e| Regexp.new(e, @regexp_options) =~ string }.compact.min end end class DictionaryMatcherTest < Test::Unit::TestCase def test_acceptance # creates a new empty matcher dm=DictionaryMatcher.new # adds strings to the matcher dm << "string" dm << "Ruby" # determines whether a given word was one of those added to the matcher assert_equal true, dm.include?("Ruby") # => true assert_equal false, dm.include?("missing") # => false assert_equal false, dm.include?("stringing you along") # => false # Regexp-like substing search assert_equal 5, dm =~ "long string" # => 5 assert_equal nil, dm =~ "rub you the wrong way" # => nil # will automatically work as a result of implementing # DictionaryMatcher#=~ (see String#=~) assert_equal 5, "long string" =~ dm # => true end def test_include_eh dm = DictionaryMatcher.new(['string', 'ruby', 'foo']) assert_equal true, dm.include?('string' ) assert_equal true, dm.include?('ruby' ) assert_equal true, dm.include?('foo' ) assert_equal false, dm.include?('stringa') assert_equal false, dm.include?('astring') end def test_equals_tilde dm = DictionaryMatcher.new(['string', 'ruby', 'foo']) assert_equal 0, dm =~ 'string' assert_equal 0, dm =~ 'string two' assert_equal 6, dm =~ 'three string' assert_equal 5, dm =~ 'four string five' assert_equal nil, dm =~ 'strng' assert_equal 0, 'string' =~ dm assert_equal 2, 'a string b' =~ dm assert_equal nil, 'strng' =~ dm end def test_case_sensitivity dm = DictionaryMatcher.new(['Foo','bar']) assert_equal 0, dm =~ 'Foo' assert_equal 0, dm =~ 'bar' assert_equal nil, dm =~ 'foo' assert_equal nil, dm =~ 'Bar' end def test_case_insensitivity dm = DictionaryMatcher.new(['Foo','bar'], true) assert_equal 0, dm =~ 'Foo' assert_equal 0, dm =~ 'bar' assert_equal 0, dm =~ 'foo' assert_equal 0, dm =~ 'Bar' end def test_greediness dm = DictionaryMatcher.new(['hi','child']) r = /hi|child/ assert_equal r =~ 'children', dm =~ 'children' dm = DictionaryMatcher.new(['child','hi']) r = /child|hi/ assert_equal r =~ 'children', dm =~ 'children' end end