 Public service announcement, if you see an organizer, thank an organizer. All right, so Rubyists, we love the innumerable module. We call it powerful, simple, elegant. It's how modules should be made. It's why we fall in love with Ruby. In contrast, here's what some things that Rubyists say about enumerator. I don't get it. That's ugly. Why would I ever use this? This seems like a big hack. Something about enumerator doesn't quite feel right. It doesn't feel like the Ruby way. It's not clean, concise, or elegant. It's awkward. We may even be tempted to call the RuboCops on enumerator. Thankfully, we don't have to deal with the PHP police. They say you are all wrong. It's also illegal. This makes me feel bad for enumerator. I want to give it some love because I believe it to be an amazing tool to have in your repertoire. But I haven't always felt this way. When I started with Ruby, I didn't get it and I didn't even know much about it. So as Luke referenced, I first started in Ruby back in 2008 and I joined WePlay, a youth sports social network where I worked with some of the most talented developers in the Ruby community, some of the 9.10 club that we saw earlier. We had built a Google Calendar clone for team scheduling and at some point, we were asked to add recurring events so coaches could easily repeat practices and games. So you can imagine our sprint planning. We were very confident. We discussed it and thought it would be straightforward. Just take our existing events and make them repeatable, right? So we estimated something like four days and you can probably guess we were wrong. We were way off. It took well over a month just to introduce the basics of recurring events. It turns out this was a challenging problem for us and it was humbling. Keep in mind this was still early in the game for Rails so we couldn't rely on all the plugins we have today. And one thing among many we were missing was a way to model infinitely repeating events in Ruby. So think about it for a second. How would you represent an abstraction like the second Tuesday of every month forever so you can enumerate and query dates in that sequence? Turns out as I've come to learn, one way to do it is use enumerator. And today we're gonna see why. So a quick recap from the Ruby docs. It's a class for internal and external iteration. Turns out you can enumerate a rise, any object by calling the two enume method. It's mixed into all Ruby objects, two enume returns an enumerator. It's enumerable, so you can call each map select. You can use the next method repeatedly for so-called external iteration. But I don't find the docs incredibly inspiring nor do they do a great job of demonstrating what enumerators are capable of. So I'd like to try it. So for one, enumerators help us implement the generator pattern in Ruby. Now I don't mean Rails generators and I don't mean these generators. I mean the fundamental abstraction for producing data on the fly. Generators can pause and resume execution control as they emit multiple values and this makes them a powerful building block across many languages for behavior like list comprehension, lazy evaluation and asynchronous operations. So they're very powerful concepts, but they also come with some baggage, depending on the community. So generators were only recently introduced into JavaScript in ES 2015. And some think they're harmful due to potential performance concerns. The venerable Airbnb style guides simply don't use generators. Others recognize their importance, but kind of feel bad for generators. But there's still, there's being used for next generation web frameworks in Node.js and the much anticipated async await feature. You get a little different perspective on Python where generators are held in high regard. Talk to an experienced Pythonista and you'll likely hear praise. Generators are awesome. So generators, a key benefit is that they let us be lazy. And I'm actually gonna use some Python code to show what I mean. So imagine we write a Fibonacci function, given n, return the first n values of Fibonacci. So we could start with an empty list. We could loop n times, calculate and append each member of the sequence to the list, then return the result. Now we can iterate through this list with a for loop. So this is an eager expression. All the values are calculated before the function returns. Everything is produced in memory up front. Well, let's turn this into a generator. We replaced our imperative, eager list manipulation with a yield statement. In Python, this means the function now returns a generator object that can emit members of the sequence on the fly. It's now lazy. The generator won't produce values until they're needed for iteration. Guess what, we can do this in Ruby. So let's port the Python Fibonacci function to Ruby almost line by line. It's really just changing tabs to spaces. There's just one problem. To make this equivalent to the Python method, we need its return value to be an innumerable generator and this method is not. So we can enumeratorize it. We're gonna add a guard clause that returns an enumerator when this method is called without a block. Now drink this in for a second. This looks kind of ugly, doesn't it? We're converting an object to an enumerator. We're passing in this magic method name method. We're using a conditional. It's a little difficult to wrap our heads around. The big win, though, is now we've converted this to an enumerator that can lazily generate the sequence as an enumerable. So in other words, we can use map, find, select, and our favorite enumerable methods on this Fibonacci enumerator. It's kind of cool. In case you think I'm making up this term enumeratorize, note that I stole it from the MRI source code for the two enum definition in enumerator.c. Yes, naming things is really hard. So enumerators can also be chained together to stream values lazily, useful for large or memory-intensive data sets. So imagine an infinite range. We can't actually process the data with enumerable methods because they're eager by default. This map call will never finish. Well, we can insert the lazy method. It creates an enumerator pipeline that can stream values. Now we can filter and reduce this infinite range to get a result here. So how is this possible? So lazy augments the chain, so how data is processed. So the eager pipeline processes each member of the collection before moving on to the next step. And the lazy version, on the other hand, passes data all the way down the chain before moving on to the next member. We can potentially terminate the iteration early, ideal for working with a generated data set. So enumerators help us solve difficult problems that would otherwise be difficult to perform eagerly. So think streaming API clients, processing large files or generating infinite sequences like recurring events. So all these years later, after absorbing all the stuff about generators and laziness, my hair is migrated from my head to my face. It recently dawned on me, we can model event recurrence with an enumerator. So I wrote a recurrence abstraction and at its heart is an enumerator which can lazily yield successive date times in a recurrence with the potential to generate these elements indefinitely. So that's right, I enumeratorized it. This is all packaged up in a gem called Montrose. It's for modeling, recurring events in Ruby. You can check it out on GitHub or ask me about it later. So the next time you find yourself creating a method to return an eagerly created collection, you might wanna consider whether to make it lazy. I like to think of this as a choice between Costco and Netflix. So you can choose to buy in bulk in potentially wasteful quantities all up front or be flexible and go on demand. Neither is right or wrong, but it may depend on the problem you're trying to solve. Costco covers more of your basic needs, but I personally find Netflix to be a lot more fun. And what could be more Ruby than that? So I think enumerator is beautiful because at a high level, it gives us this option of laziness. Not something you necessarily need all the time, but it may come in handy. So even if enumerator is not your thing, my takeaway for you is to look at the beauty and even an ugly code because sometimes it can teach us something and it did for me. My name is Ross Kaffenberger. I'm Rosta on the internet. Thank you very much.