Make fancy enums with `enum_for`

Did you know you can make your own enumerators in Ruby?

```ruby
e = Enumerator.new do |y|
 [1,2,3].each { |i| y << i }
end

e.next    # => 1
e.next    # => 2
e.rewind
e.next => # => 1
```

Methods like `each` help convert things to an enumerable (using `to_enum`), but there is another way to create enums in Ruby. `enum_for` takes one argument which points to a method to bind to for enumeration. It allows make something enumerable when it technically isn't, or when we can't/don't want to.

```ruby
class DoReMi
  def sing
    lyrics.each { |l| yield l }
  end

  private

  def lyrics
    [
      "Doe, a deer, a female deer",
      ...
    ]
  end
end
```

Use `enum_for` to enumerate at your own pace. Let's learn to shout the song backwards!

```ruby
d = DoReMi.new
d.sing { |l| puts l }
# => Doe, a deer, a female deer
# => ...
e = d.enum_for :sing
e.map { |l| l.upcase }.reverse.each { |l| puts l }
# => ME, A NAME I CALL MYSELF
# => ...

# Wait, what's the last lyric again?
e.rewind
e.next.upcase # => "DOE, A DEER, A FEMALE DEER"
```

douglasgreyling
January 10, 2022