Make fancy enums with `enum_for`
Did you know you can make your own enumerators in 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.
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!
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"
Tweet