Understanding and using Ruby's powerful #grep method
Ruby is known for its many handy methods. I’d like to take a look at one that is a little bit less known, but quite powerful nonetheless: the
About the method
#grep is one of many instance methods defined on the
Enumerable module. This essentially means that you can use it on all Ruby classes that include this module, e.g.
Enumerable module is the place where many other popular “collection” methods are defined -
#select, and the like. Whatever Ruby object you can use the
#map on, you should be able to use the
#grep on as well.
“Getting a #grep”
Let’s see an example usage of the
Seems pretty handy, right? And that’s just one way of using it. But before showing more examples, let’s deconstruct this to understand exactly how it works.
What happens under the hood here could be mimicked with a code like this:
Or, more generally:
Notice a few things here:
- The return value will always be an array. The length of this array will be between 0 (empty), and the size of the original collection (which is exactly how
- We are using the triple equals (
#===) method (“operator”). The
#===is probably worthy of a separate article. But for now, we can just recall that it’s implemented in classes as sort of a “lighter” (meaning: less strict) equality method (also called “case” equality due to its usage in case statements). We can illustrate the difference between regular and “case” equality with an example:
We don’t have to limit ourselves to regexes. Any object could be passed as a “pattern” to compare against.
The triple equals method is invoked on the given pattern, not the elements of the collection. (The
pattern === elementbit is of course just a syntactical sugar for
pattern.=== element- stripping out the ‘sugar’ exposes the method invocation). Invoking the method on the pattern makes sense, as it’s this object that should “know” when something is passing its “light” equality requirements. Notice the difference here:
When and how to use it
Enough theory. Let’s get down to it and look at some concrete situations where the
#grep method might come in very handy to you.
#grep with a Regexp
You can easily match strings with a Regexp pattern.
Apart from handling collections of strings in the code, I find the
#grep method to be very handy for… recalling things (e.g. by performing a quick lookup in the terminal). These examples should illustrate the idea:
Regexp#=== works with symbols just as it does with strings)
#grep with a Range
Range#=== checks the inclusion of Numeric values in the given range. This means that we can pass a range to grep to quickly filter values falling within the range.
#grep with a class name Constant
#grep with any object
#=== method in Ruby is implemented on an
Object, you can pass any descendant of this class to the
Object class, the
#=== method behaves the same way as
#==. It’s up to descending class to implement (or not) a different meaning between the two.
The opposite: #grep_v
#select has an opposite
#reject method, there is also a
#grep_v method that behaves like you would imagine - it rejects the matched objects, similar to how this code would:
Passing a block
#grep_v are utilizing a block if one is supplied. The block is used to transform the matched values before returning them in an array (just like chaining a
#select would). E.g.
The same operation without a #grep would probably look something like that:
As you can see, the
#grep method is pretty powerful! If you haven’t already, add it to your developer’s arsenal and see where it can help you in your work.
Are you using the
#grep method in your project? Please share in the comments below!
And if your Ruby project suffers from slow build times, consider using Knapsack Pro to improve the productivity and delivery times of your team!