<commit_before>---
title: "What's new in Ruby 2.3 Enumerable"
author: <NAME>
published: true
summary: A closer look at Enumerable's grep_v and chunk_when
description: Ruby 2.3 introduced a couple new additions to the Enumerable API that provide some nice variations on existing methods
pull_image: 'https://rossta.net/assets/images/blog/stock/dark-brown-milk-candy-pexels-photo.jpg'
series: Enumerable
tags:
  - Code
  - Ruby
  - Enumerable
---

You may have heard [Ruby 2.3 dropped](https://www.ruby-lang.org/en/news/2015/12/25/ruby-2-3-0-released/) on Christmas this past year. Two new `Enumerable` instance methods were added, `grep_v` and `chunk_while` and each are variations on enumerable methods we already had. We'll dissect both here below.

#### Triple Lindey

Grep allows you to select members of a collection that match an expression. That expression is `some_object === item`.

What does "triple equals" do? Well, in Ruby, as in most languages, that answer
is complicated. Since we can define this method however we want in our own
classes, it can mean anything. But, most commonly:

> if `a` === `b`, then `b` is a subset of `a`

How about a few examples.

```ruby
Symbol === :foo     # => true, :foo is a symbol
String === "foo"    # => "foo", is a string
Symbol === "foo"    # => "foo", is not a symbol
String === :foo     # => :foo, is not a string

/foo/ === "foobar"  # => true, "foobar" matches /foo/
(1..10) === 2       # => true, 2 is in the range 1..10
```

We **could** use `select` to filter out items of a collection with the `===` like
so:

```ruby
1.upto(20).select { |i| (6..10) === i } # => [6, 7, 8, 9, 10]
```

But this is what `grep` is for:

```ruby
1.upto(10).grep(6..8) # => [6, 7, 8]
```

So `grep` is like saying "gimme all the items in the given set".

To get all the items *not* included, use `grep_v`:

```ruby
1.upto(10).grep_v(6..8)
=> [1, 2, 3, 4, 5, 9, 10]
```

Define `===` on any class or object to take advantage of filtering with `grep` and `grep_v` in other contexts.

#### Chunking

The `Enumerable` module provides several methods for enumerating adjacent
members of a collection, including `slice_when`, `slice_before`, `slice_after`,
`each_cons`, and, not surprisingly, `chunk`. Ruby 2.3 offers yet another
chunking method, `chunk_while`.

Before diving into `chunk_while`, let's look at its relatives, `chunk` and `slice_when`.

For the following examples, we'll enumerate over recurring events given by the<commit_msg>Edits to new enumerable methods post<commit_after>---
title: "What's new in Ruby 2.3 Enumerable"
author: <NAME>
published: true
summary: A closer look at Enumerable's grep_v and chunk_when
description: Ruby 2.3 introduced a couple new additions to the Enumerable API that provide some nice variations on existing methods
pull_image: 'https://rossta.net/assets/images/blog/stock/dark-brown-milk-candy-pexels-photo.jpg'
series: Enumerable
tags:
  - Code
  - Ruby
  - Enumerable
---

You may have heard [Ruby 2.3 dropped](https://www.ruby-lang.org/en/news/2015/12/25/ruby-2-3-0-released/) on Christmas this past year. Two new `Enumerable` instance methods were added, `grep_v` and `chunk_while`, both of which are variations on other `Enumerable` methods. We'll dissect both here below.

#### Triple Lindey

Grep allows you to select members of a collection that match an expression. That expression is `some_object === item`.

What does "triple equals" do? Well, in Ruby, as in most languages, that answer is complicated. Since we can define this method however we want in our own classes, it can mean anything. But, most commonly, it is a loose way of asking whether an object belongs to a certain group:

> if `a` === `b`, then `b` is a subset of `a`

A few examples:

```ruby
Symbol === :foo     # => true, :foo is a symbol
String === "foo"    # => "foo", is a string
Symbol === "foo"    # => "foo", is not a symbol
String === :foo     # => :foo, is not a string

/foo/ === "foobar"  # => true, "foobar" matches /foo/
(1..10) === 2       # => true, 2 is in the range 1..10
```

We *could* use `select` to filter out items of a collection with the `===` like so:

```ruby
1.upto(20).select { |i| (6..10) === i } # => [6, 7, 8, 9, 10]
```

But this is what `grep` is for:

```ruby
1.upto(10).grep(6..8) # => [6, 7, 8]
```

So `grep` is like saying "gimme all the items in the given set".

To get all the items *not* included, use `grep_v`:

```ruby
1.upto(10).grep_v(6..8)
=> [1, 2, 3, 4, 5, 9, 10]
```

It's probably most likely that you'd use `grep` and `grep_v` with a regular expression, like
to select all the months that end in "er":

```ruby
MONTHS.grep(/er$/)
=> ["September", "October", "November", "December"]
```

Define `===` on any class or object to take advantage of filtering with `grep` and `grep_v` in other contexts.

#### Chunking

The `Enumerable` module provides several methods for enumerating adjacent
members of a collection, including `slice_when`, `slice_before`, `slice_after`,
`each_cons`, and, not surprisingly, `chunk`. Ruby 2.3 offers yet another
chunking method, `chunk_while`.

Before diving into `chunk_while`, let's look at its relatives, `chunk` and `slice_when`.

For the following examples, we'll enumerate over recurring events given by the
{'fraction_non_alphanumeric': 0.13687416714258518, 'fraction_numerical': 0.022844089091947458, 'mean_word_length': 3.9472693032015065, 'pattern_counts': {'":': 1, '<': 5, '<?xml version=': 0, '>': 26, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '934480', 'n_tokens_mistral': 1829, 'n_tokens_neox': 1669, 'n_words': 730}