Search code examples
rubyregexbooleancase-insensitivenomethoderror

Ruby statements - case insensitivity?


I have a problem, I'm trying to create a method that finds words (or characters sequences)in a string and doesn't care about case sensitivity. For example both "ExAmPLE" and "example" would both return true. Here's my code

class WordMethods
  # Finds words in a string and returns true or false
  def word_finder?(string, word) # A boolean method that takes in one argument, word (a string)
    return true if string.include?(word, /i/) # trying to use regex for case insensitive
  end
word_finder?("A gold brown fox", "GoLD") # should return true
end

When I run the code on irb I get the following error.

NoMethodError: undefined method `word_finder?' for WordMethods:Class

I don't understand. I defined my method inside the class, and then called it inside the class. I don't know where I'm going wrong. I am a beginner in ruby and practicing some example questions I found over the internet. This is one of them.

Any help will be appreciated


Solution

  • You can use regular expressions in Ruby to search for something within a string, and make your search case-insensitive simply by adding i onto the end of the regular expression, like this:

    "A gold brown fox" =~ /GoLD/i    #=> 2
    

    This returns 2, which is the index of the match. If there were no match, it would return nil. This works in a boolean context because the value 2 acts like "true" in Ruby, whereas nil acts as "false." Of course, if you really want it to return true or false you can prefix the expression with !! to force it to be a boolean:

    !!("A gold brown fox" =~ /GoLD/i)   #=> true
    

    This syntax is simple enough, but if you want to create a word_finder? method, you could do something like this:

    class String
      def word_finder?(word)
        !!(self =~ Regexp.new(word, true))
      end
    end
    
    "A gold brown fox".word_finder?("GoLD")    #=> true
    

    Three things to note with the code above:

    1. We're monkey-patching the String class, adding a word_finder? method. This method is called by adding .word_finder? after a string, and the value of the string is represented within the function as self.

    2. Creating a Regexp pattern via Regexp.new(word, true) returns a case-insensitive regular expression of that word. So, in this case, Regexp.new("GoLD", true) evaluates to /GoLD/i.

    3. We enclose the self =~ Regexp.new(word, true) in !!( ... ) so that we get true or false, not the index of the match or nil.

    Reference:
    http://www.regular-expressions.info/ruby.html
    http://www.ruby-doc.org/core-2.1.1/Regexp.html#method-c-new
    http://www.ruby-doc.org/core-2.1.2/String.html#method-i-3D-7E