mirror of
https://github.com/jbranchaud/til
synced 2026-01-02 22:58:01 +00:00
1.3 KiB
1.3 KiB
Turning Any Class Into An Enumerator
At the core of any enumerator is the ability to respond to an #each call.
With that in mind, we prepare any class for being turned into an enumerator.
Consider this class SquaresCollection that allows you to turn an array of
integers into an array of its squares.
class SquaresCollection
def initialize(items)
@items = items
end
def run
@items.map { |item| item * item }
end
end
SquaresCollection.new([1,2,3]).run #=> [1,4,9]
We can work with this, but it opts out of Ruby's enumerator offerings.
We can, instead, provide an #each method which allows instances of our
SquaresCollection class to be turned into enumerators.
class SquaresCollection
def initialize(items)
@items = items
end
def each
return enum_for(:each) unless block_given?
@items.each do |item|
yield item * item
end
end
end
Here is how we can use it:
sc = SquaresCollection.new([1,2,3])
puts sc.to_enum
#=> <Enumerator ...>
puts sc.to_enum.map { |item| "* #{item} *" }
#=> ["* 1 *", "* 4 *", "* 9 *"]
The #to_enum method
looks for an #each method on the instance's class and uses that to create an
enumerator.