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
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.