From 52d5def86e058ca319bf744f5bf0597568ca8dad Mon Sep 17 00:00:00 2001 From: jbranchaud Date: Sun, 11 Aug 2019 10:32:24 -0500 Subject: [PATCH] Add Turning Any Class Into An Enumerator as a ruby til --- README.md | 3 +- ruby/turning-any-class-into-an-enumerator.md | 60 ++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 ruby/turning-any-class-into-an-enumerator.md diff --git a/README.md b/README.md index 4a5eb45..5ceeda6 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ smart people at [Hashrocket](http://hashrocket.com/). For a steady stream of TILs from a variety of rocketeers, checkout [til.hashrocket.com](https://til.hashrocket.com/). -_832 TILs and counting..._ +_833 TILs and counting..._ --- @@ -683,6 +683,7 @@ _832 TILs and counting..._ - [Squeeze Out The Extra Space](ruby/squeeze-out-the-extra-space.md) - [String Interpolation With Instance Variables](ruby/string-interpolation-with-instance-variables.md) - [Summing Collections](ruby/summing-collections.md) +- [Turning Any Class Into An Enumerator](ruby/turning-any-class-into-an-enumerator.md) - [Turning Things Into Hashes](ruby/turning-things-into-hashes.md) - [Uncaught Exceptions In Pry](ruby/uncaught-exceptions-in-pry.md) - [`undef_method` And The Inheritance Hierarchy](ruby/undef-method-and-the-inheritance-hierarchy.md) diff --git a/ruby/turning-any-class-into-an-enumerator.md b/ruby/turning-any-class-into-an-enumerator.md new file mode 100644 index 0000000..7410245 --- /dev/null +++ b/ruby/turning-any-class-into-an-enumerator.md @@ -0,0 +1,60 @@ +# 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. + +```ruby +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. + +```ruby +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: + +```ruby +sc = SquaresCollection.new([1,2,3]) + +puts sc.to_enum +#=> + +puts sc.to_enum.map { |item| "* #{item} *" } +#=> ["* 1 *", "* 4 *", "* 9 *"] +``` + +The [`#to_enum`](https://devdocs.io/ruby~2.5/object#method-i-to_enum) method +looks for an `#each` method on the instance's class and uses that to create an +enumerator. + +[source](https://blog.arkency.com/2014/01/ruby-to-enum-for-enumerator/)