---
title: "Ruby 3.1 adds Enumerable#compact and Enumerator::Lazy#compact"
description: "Ruby 3.1 adds Enumerable#compact and Enumerator::Lazy#compact"
canonical_url: "https://www.bigbinary.com/blog/ruby-3-1-adds-enumerable-compact"
markdown_url: "https://www.bigbinary.com/blog/ruby-3-1-adds-enumerable-compact.md"
---

# Ruby 3.1 adds Enumerable#compact and Enumerator::Lazy#compact

Ruby 3.1 adds Enumerable#compact and Enumerator::Lazy#compact

- Author: Ashik Salman
- Published: April 6, 2021
- Categories: Ruby 3.1, Ruby

We are familiar with the
[compact](https://apidock.com/ruby/v1_9_3_392/Array/compact) method associated
with arrays. The `compact` method returns a copy of the array after removing all
`nil` elements.

Ruby 3.1 introduces the `compact` method in the `Enumerable` module. Now we can
use the `compact` method along with the `Enumerator` and `Enumerator::Lazy`
classes which include the `Enumerable` module.

## Before Ruby 3.1

```ruby
=> enum = [1, nil, 3, nil, 5].to_enum
=> #<Enumerator: ...>

=> enum.compact
=> NoMethodError (undefined method `compact' for #<Enumerator: [1, nil, 3, nil, 5]:each>)

=>  enum.reject { |x| x.nil? }
=> [1, 3, 5]
```

## After Ruby 3.1

```ruby
=> enum = [1, nil, 3, nil, 5].to_enum
=> #<Enumerator: ...>

=> enum.compact
=> [1, 3, 5]
```

We can access the `compact` method to remove all `nil` occurrences from any
classes where we include the `Enumerable` module.

```ruby
class Person
  include Enumerable

  attr_accessor :names

  def initialize(names = [])
    @names = names
  end

  def each &block
    @names.each(&block)
  end
end

=> list = Person.new(["John", nil, "James", nil])
=> #<Person:0x0000000101cd3de8 @names=["John", nil, "James", nil]>

=> list.compact
=> ["John", "James"]
```

Similarly, lazy evaluation can be chained with the `compact` method to remove
all `nil` entries from the `Enumerator` collection.

```ruby
=> enum = [1, nil, 3, nil, 5].to_enum.lazy.compact
=> #<Enumerator::Lazy: ...>

=> enum.force
=> [1, 3, 5]


=> list = Person.new(["John", nil, "James", nil]).lazy.compact
=> #<Enumerator::Lazy: ...>

=> list.force
=> ["John", "James"]
```

Here's the relevant [pull request](https://github.com/ruby/ruby/pull/3851) and
[feature discussion](https://bugs.ruby-lang.org/issues/17312) for this change.

## Links

- [Human page](https://www.bigbinary.com/blog/ruby-3-1-adds-enumerable-compact)
