String Inquiry

Compare Strings Using Inquiry

1 min read

Similar to the ArrayInquirer class, which tests if an array contains a value, the ActiveSupport::StringInquirer class provides a nice way to compare two strings. Use it when you have an internal method that returns a string, and the consumer of that method needs to compare it with another string.

def env
  ActiveSupport::StringInquirer.new('production')
end

env.production? # true
env.local?      # false

Behind the scenes, implementing this needs some metaprogramming, as Rails can't know the value of the string in advance.  

def method_missing(method_name, *arguments)
  if method_name.end_with?("?")
    self == method_name[0..-2]
  else
    super
  end
end

The Ruby interpreter calls the method_missing method when it can't find the invoked method. If the method name ends with a ?,  it compares the original string with the method's name minus the ?.

The 'inquiry' Shortcut

Rails further simplifies it by adding the inquiry extension method on String which returns an instance of the StringInquirer class.

def env
  'production'.inquiry
end

env.production? # true
env.local?      # false

Here's the implementation of the String#inquiry method. It instantiates the StringInquirer class, passing self which is the string itself.

# activesupport/lib/active_support/core_ext/string/inquiry.rb

class String
  def inquiry
    ActiveSupport::StringInquirer.new(self)
  end
end

I love how much Rails cares about beautiful code and goes above and beyond to simplify its external API.

Hope you learned something new. Let me know if you liked this post or have any feedback. I look forward to hearing from you.