Ruby’s Enumerable#grep selects elements for which the supplied expression returns true when applied with case equality (===). Its familiar use is filtering strings with a regular expression, but the same mechanism supports classes, ranges, and other objects. section 10.3.3 section 11.7.4
>> colors = %w(red orange yellow green blue indigo violet)
=> ["red", "orange", "yellow", "green", "blue", "indigo", "violet"]
>> colors.grep(/o/)
=> ["orange", "yellow", "indigo", "violet"]
A regular expression selects the colors containing the letter o. section 10.3.3
Conceptually, enumerable.grep(expression) behaves like enumerable.select { |element| expression === element }. The expression controls the meaning of matching: String selects strings, while 50..100 selects numbers included in that range. section 10.3.3
>> miscellany = [75, "hello", 10...20, "goodbye"]
=> [75, "hello", 10...20, "goodbye"]
>> miscellany.grep(String) 1
=> ["hello", "goodbye"] 1
>> miscellany.grep(50..100) 2
=> [75] 2
The same grep call uses String as a type test and a Range as an inclusion test. section 10.3.3
Regular expressions make grep concise, but their matching remains type-specific:
- grep(/pattern/) selects only elements for which the regular expression’s === match succeeds. section 11.7.4
- Numbers are not automatically converted to strings, so [1, 2, 3].grep(/1/) returns an empty array. section 11.7.4
- grep(expression) { |item| ... } filters first, then yields each selected item and collects the block’s return values. section 10.3.3 section 11.7.4
>> colors = %w(red orange yellow green blue indigo violet)
=> ["red", "orange", "yellow", "green", "blue", "indigo", "violet"]
>> colors.grep(/o/) {|color| color.capitalize }
=> ["Orange", "Yellow", "Indigo", "Violet"]
A block transforms each selected color, combining filtering with mapping in one call. section 10.3.3
Filtering introspection results
Because symbols exhibit string-like behavior for grep, an object’s method list can be searched with a regular expression: string.methods.grep(/case/).sort returns method names involving case. A pattern such as /.!/ finds names ending in a bang rather than merely containing !. section 15.2.1
grep is therefore a compact selection tool whose behavior comes from the argument’s implementation of ===. Use it when the matching expression already captures the predicate; use select when the condition needs an ordinary block. section 10.3.3 section 11.7.4
