 comes from and where it's going in 1.9. And there may be a little bit of a digression as well to talk about each in your own classes and also the awesomeness that is the enumerable module. So I hope you enjoy the talk. I hope this is interesting. Some of you in spirit of the 10th anniversary may be looking at that bit of Ruby's origins. I think each iteration in Ruby is a very foundational concept. It's also very telling about some of Ruby's goals and the way that Ruby works. If you understand, I think, if you understand each, you understand a lot about Ruby. So hopefully this will be somewhat informing as well. And I understand from listening to Aaron's talk previously, he's in the other room stealing all of the people who would otherwise be at this talk. Yeah, sure, let me... Is this better? Yeah. Okay, all right. So I understand from Aaron that it's very important to have a provocative title, so I have provided one. And I... Like I said, my name is Ryan Hendricks. I tweet my blog. I work at a company called PHP Fog. I don't do PHP, I do Ruby. We do automated PHP deployment in the cloud. It's awesome. But that's not what I'm talking about today. I'm talking about iteration. And I'm going to discuss external iteration, internal iteration, generators, and enumerators. I'm just going to talk a bit about where they came from and how we used them in our scheme. External iteration is a concept that you're probably all familiar with. This is Java. Java didn't create external iteration, but it's probably the place that you've seen it most often. External iteration is iterating over an object by using an object external to that object to provide the iteration. So this iterator object here is aware of how to take this list and get the next object in sequence. And this loop says that while there is a next object, iterate by taking the next object and then continue on to the next object in the loop. And while Ruby can do external iteration, we don't often do it because Ruby has more powerful iteration concepts like internal iteration. Internal iteration is the collection object itself is able to enumerate its elements. And this is probably how you usually iterate when you see Ruby. And I'm going to talk a bit about how each works and how each is used as the basis of the enumerable module to provide a lot of other powerful behavior that are also powerful and familiar with it. So the each method is found in a number of places in Ruby, most commonly array, caching, string, but also in a number of other places. The dir class, io, range, sex, string io, struct. A bunch of others. And also you can have an each in your own class. And I thought that explaining how to write each might give us a good understanding of how internal iteration works in Ruby at a deeper level. So I'm going to talk about writing each using a linked list class. How many of you are familiar with a linked list? Let me try that again. How many of you are not familiar with a linked list? Really? Okay. A linked list is a collection class that uses objects that have a pointer to the next object. So you start with the first object, then you traverse those pointers to get to the next object and the next object until you run out of next objects. And we can write a linked list in Ruby by using a struct to represent each object in the collection. And that struct has a pointer to the next object and a container for the thing that it is representing. And we can initialize a list by pushing all of the arguments onto the list. And push is some magic that I want to explain. It basically creates a new node and it assigns its object and it assigns the previous nodes next to that node so it can be traversed, too. So how would we write each for a linked list class? First, let's talk about the semantics of each. In the original Ruby pickaxe book, each is listed in the documentation as a method that calls a block once for each element in self and passes that element as a parameter. So these are the semantics of each. It calls the block once for each element. It passes the element as a parameter and it doesn't mention this, but it also always returns self. Thanks, Aaron. So let's talk about how we can implement each. First of all, we're going to define each for our linked list class by taking the first node part of the implementation of the linked list object because it has a first access service and it's very good for the first object. So we're going to take that first node and if there's a node, we're going to call the block. We're going to heal. That's not a very complete each. It doesn't iterate but we can actually call the block on the object. So let's change that a bit. Let's start out by calling it once for each element. So we'll start out by turning this if into a while and then we'll have the heal of heal to the object by passing it to the if. And one of the things that you may notice here is that this is a demonstration that an if is a degenerate while takes, which is slightly interesting. But more interesting is we now are able to... We've satisfied the first part of the cementing of each. We iterate over each object in the linked list and we pass that object as the parameter to the block using the unit. And then finally we return something. So now we have each, let's do something with it. Let's take our linked list class and let's create a linked list object and we do that in IRB and that's ugly and I don't like that. So let's dive right really quickly and write a nice constructor method. Can you all read that? We'll write a nice constructor method that delegates to new and then we'll write a nice output method or inspect which is what IRB uses to print to the console. And now we can use IRB and we can create a linked list on the first line there and then its IRB output looks like the bottom line which I think is a lot nicer. So we can use that now to demonstrate the behavior of each. That might be a little small. Can you all read that? It's a linked list of the integers one through four and for each item in the list it prints out the item. And so before we go any further let's look at the inspect and ask ourselves where did this 2A come from? We didn't define it. How did it get there? The answer is that it's inside innumerable so we're going to talk about innumerable right now and how innumerable can add behavior to your collection classes that you define yourself and why it's awesome. So innumerable in the pickaxe is a mix-in provides collection classes with reversal and searching methods and a bunch of other cool stuff sorting and it provides 2A. So if we include innumerable then that gives us 2A and we can use that in our inspect. So let's talk for a second about innumerable and how it uses each as the basis method to provide a lot of behavior for all of the objects in Ruby that have each method that conforms to the contract that we talked about earlier in semantics. Let's pick a few innumerable methods and talk about implementing them and instead of calling it innumerable let's call it this because that's a valid module name. And so let's start with 2A. Here's a definition of 2A for our innumerable. We start out with an accumulator variable and this array variable holds an empty array and for each item we append, we push that item into the array and then we return the array. That's 2A as implemented in innumerable. Collect is similar to 2A but instead of pushing the item onto the array it pushes the return value of yielding the item to a block. How many of you are familiar with yield? How many of you are not familiar with yield? Awesome, I can skip like five slides but I'm not going to. Yield is very foundational. Yield and blocks work together to do a lot of awesome stuff that I'm sure you're all familiar with but I'm going to talk about it anyway. Yield invokes a code in a block passing any arguments and then when the block exits the control picks back up immediately thereafter. So yield we can demonstrate thusly we define a method that just has yield in it we call that method with a block and then the block is executed. Yield with an argument works similarly we define that method to yield the argument we call it with an argument and a block and we can see that that block has a block level variable and it is interpolated into the string. So let's go back to our collect now that we know as we already did now that we know about the behavior of yield we can see that it takes the argument and it yields it to the block that you define. So let's talk about now that we have collect here is detect return that item if the return value of yielding it to the block is truthy and you're all familiar with the semantics of truthiness and ruby if it's nil or false it's falsey and if it's anything else it's truthy. So select is similar but instead of returning the first item it yields that item if the result of yielding is a block it's full. So these implementations that I've shown you are somewhat naive they don't handle all of the possible arguments to some of the methods. If you want to see a full implementation I would suggest you look at Rubinius which is of course ruby written in ruby and I would say that if there are C constructs in ruby that you want to understand at ruby methods written in C reading their rubinius equivalent is the best way to drop what they do without having to parse C in your brain which for some of you can be painful like me. So now that we have our linked list we're going to include our own innumerable model and we can keep the same QA in our inspect and it'll still work. So what I want to talk to you about briefly now that we've covered innumerable is how you can use the idea of extending basis functionality with mixings to add behavior to objects that share some sort of basis behavior. So a basis method is a core method from which mixings functionality is described. A numerable basis method is each meaning that any object that you have that shares an each method that conforms to the semantics we discussed you can drop in innumerable and it'll just work and it'll provide you with all of the methods in innumerable. Likewise comparables basis method is this queer what's it called a vodka? Vodka equals vodka can you call it that? I've heard it called a spaceship. If you have a spaceship operator that returns a 1, 0, or negative 1 depending on what order two objects are relative to each other including comparable will derive all of the less than, greater than greater than or equals two methods from that. So in addition to talking about using basis methods and extending those methods with mixing I want to talk to you about some of the core behavior of Ruby and how it relates to classes that you write yourself and how your objects play with other objects in Ruby's ecosystem. If you're writing a collection its iteration method should be named each if you want your object to do what you expect as a hash key it'll depend on the implementation of hash and the EQL question mark method for determining whether two objects are the same hash key. Also the Ruby set class and summary methods like Intersection, Union, and Unique use a hash internally so you're trying to get to the intersection of two arrays of your own objects and it's not working what you actually have to do is you have to make them work in a hash as a key property for that to work. So we're going to talk very briefly about that about making your making your objects play well inside a hash because I think this is a good way to extrapolate a lot of other behaviors in the Ruby ecosystem and how you should write your objects to take advantage of them of their respective behaviors. So caches depend on a hash method and an equal method. A hash function as most of you probably know is a function that takes an object, in this case an object in Ruby and returns an integer and that integer should as much as possible be unique. The reason that caches use the equal method as well is because there are more objects than there are integers so sometimes there's a hash collision and two objects have a hash function that returns the same integer. So this may be surprising to some of you who expected only hash to be necessary but if you want your Ruby objects to work as you expect in hash keys, or as hash keys you also need to find the eql question mark. So a hash for a linked list should be unique to the list elements and should not conflict with other collections that may have the same element. So if you have a linked list with the same elements and you have a hash function so the hash method should return a different integer. And we can do that by taking a hash of its contents and XORing that with a hash of its class which will provide a unique integer at least for comparing linked lists to sets or arrays it will be unique and will prevent hash collisions. The XOR is to prevent the odd case of the original hash returning combining these two integers in such a way that they overflow into a big dump which we don't want. So the XOR will make sure that they always stay within the max names range. And finally, eql needs to be defined so that it has correct semantics and this poses the question what are the semantics of eql and how do these equivalence methods in Ruby work? The exact semantics of the equals equals the eql and the equal methods in Ruby. Cool, awesome. The equals equals method checks whether two values are equal. It doesn't check class or object ID. So a specification for equals equals is that a linked list with the same values as an array when you compare that linked list to the array using equals equals the response should be true. Equal compares the values and the class and asserts that they must both be the same. For a linked list that would be the equal method with the same values as an array should be false. You can make another method that says the two linked lists with the same values when compared using eql should be true and equal compares whether two objects are identical, that is they have the same object ID. So in this case, two linked lists with the same values should not be equal but they should be eql equal. And as a mnemonic note that the strictness of the function is a the strictness is a function of the length of the method. So back to defining equal for the linked list you can say that they're equal if their class is equal and their values their two array values are equal. Does that make sense? So the moral of the story and the reason that I went on this digression from iteration is that iteration is an example of a way that you can make your Ruby objects, in this case collection objects like a linked list work well in the Ruby ecosystem. You can use enumerable to add behavior to those collection classes that you may define to make them behave more like an array and to make them more familiar to users of your class. Likewise other objects that you define that may not be collections that may not have iteration should still be behaved nicely in the Ruby ecosystem. In Wyrite I would say that polite objects that behave as expected inside Ruby that for instance hash as expected as hash keys or when you unique an array of linked lists if they have the same values they should be considered two Ruby's. So common Ruby semantics that your class should probably implement would include inspect for human readable outputs a 2s if it's applicable some things just don't have some kind of input but a 2s will be used internally in stream interpolation and with printf a 2 proc if your object is some sort of command object that takes parameters and then evaluates some sort of command and then returns a value 2 proc may be an appropriate method to implement that it will allow Ruby to coerce your object into a block. If you apply 2f2a into 8 integer flow array and hash are loose coercion methods that is to say that Ruby's definition of strictness in this case is that a object that has a 2i doesn't have to be isomorphic to an integer it could have other properties an address for instance could have other properties but it may 2s to the string representation of the address. On the other hand 2int to array into str are for objects that are strongly related to integers arrays or strings. In fact in Ruby, core the only class that implements 2str is the exception class it's not that common to see these methods implemented but if you're for instance writing some other form of integer that uses a different representation a 2int method may be useful method for your class to have. So we were talking about iteration and I want to get back to that now. We've talked about external iteration and internal iteration. Now I want to talk about generators this is a language called Clue this is a language called Clue Clue was created at MIT by Barbara Liskov of the Liskov substitution principle thing and for students between 1974 and 1975 it's a language that has abstract data types making it somewhat of a forerunner of a lot of object-oriented concepts that we have today although we did not have other concepts that we now think are necessarily like imperatives. One of the constructs that Clue did have is a generator and a generator in this case is a way of creating an external iterator and you can see that Clue's syntax includes a very familiar method here called yields which is actually the basis of the Ruby method yield that's where it comes from. Ruby has generators as well but you don't this is 1.9 or the enumerator library is also in the 1.8 standard library but you don't use the generator directly what you use is an enumerator and here's an enumerator that creates a Fibonacci sequence. This yielder object is an enumerator yielder class and it's what's responsible for generating the next value in the sequence. That's how it uses a generator internally to provide an enumerator of an external. So it's actually an interesting combination of internal and external iteration. The external iteration of a generator is wrapped in the internal iteration of an enumerator so you can say each on an enumerator and have it behave as if it were an internal iteration but you can also say next and have it behave as if it were an external iterator. What we'll notice about this Fibonacci sequence enumerator is that enumerators can be infinite lists and they can be rainbow colored maybe not rainbow colored but definitely infinite. So you can take this Fibonacci sequence and take the first 10 values take as a method on enumerators and that makes enumerators similar to some functional programming methods on lists or arrays so you can use enumerator to do some similar things that you may do in Haskell with infinite lists and take and whatnot although I recommend not calling each on this. You might be there for a while. So in conclusion I just want to leave you hopefully with the idea that each is a great method that encapsulates a lot of the elegance and simplicity of Ruby enumerable is double great for taking Ruby's elegant internal iteration and turning it into map and collect and inject and all of the other enumeration behaviors that we love about Ruby and please use your enumeration that is responsibly don't automatically use inject when there may be a better solution. Inject actually has a use case but it is not the use case of each within the accumulation variable so you don't have to have an extra line of code. When you write your own classes try to make them play nicely with others and you should re-implement core behaviors such as hash or equal so that your object has semantics that are more appropriate to it. Look for common methods in your objects that you can extend to provide shared or familiar behaviors such as each for collections. Don't be afraid to write mixins for your objects that give them such behavior especially if they can extend common behavior in your system and the more common that behavior is the more powerful your mixin will be by enumerator for instance is a more useful mixin than comparable because more things have each and we use iteration more often. Also when you write your own objects in classes as you should be doing play nice with other developers by providing more useful input methods than new when appropriate and by giving them human readable output don't depend on the inspect provided by object it may not be very readable. Also as an example of one of the more pernicious ways that objects may not play nicely use hash and equal on your objects to define their semantics in a hash context. Finally, and this is an example of some of the power of Ruby's iteration. I want to talk about list comprehension. How many of you are familiar with list comprehension? List comprehension is more commonly seen in functional languages like Haskell allows you to basically take a list or list and comprehend over those lists into a single list. In Ruby that can be done. I'm more interested with the sort of degenerate list comprehension which is take a single list and comprehend over that into another list which is like but instead of returning every value you can use in Haskell for instance in traditional list comprehension you can use guard clauses so that for instance give me every x for every x give me x squared where x is odd or even so for instance in Ruby we might want to write a slide. We might want to write a code that looks like this. Can everyone see this? This is take the array 1,3,4 and a method called comprehend that we haven't written yet that takes every i, every integer squares it and it returns it if it's even and that gives us 4 and 16. Now how could we write this in Ruby? One way might be to use inject start with an array and then push onto the array the value of yielding the block if the value of yielding the block is truthy that's sort of like a combination of collect and select it does both the collecting and the selecting at the same time we could also just use each and the temporary accumulator variable which has the advantage of not being inject but what I found when I benchmark all of these solutions is that the most elegant solution in Ruby which is a combination of collect and then compact was also the fastest so this gives you a good example of how using the elegance of Ruby can also sometimes give you performance advantage it's not necessarily true that elegance and performance are usually exclusive so that is that is my talk I would love to answer any questions you might have we've got a few minutes left so I might have missed it but I don't think you mentioned the requirement of the semantics between equal eql, question mark and hash I'm sorry? the requirement that if two objects are respond to the eql question mark they have to have the same hash there's an implication requirement yes there's an implication that if two objects have the same eql question mark behavior they have the same hash so if two objects are equal in that sense they should have the same hash and the way that we define hash you could actually use hash to implement equal if you wanted to although I would shy away from that because it would be slightly less correct because of possible collisions so you could say equal is true with the hash because the reason for that implication is that the hash basically puts the value into a set of things that are equal we're actually may or may not be so the reason that wouldn't work is that the point of equal in the context of hashes is to differentiate between objects that otherwise collide that otherwise have the same hash key so it is true that all objects that have the same hash should be equal but it is not true that all objects that are equal should have the same hash I think it's the other way around do they flip those two? yeah it's the other way around hash is generally cheap to do equal may be expensive you're using hash to avoid to compare each other you find collisions you use whatever I meant to say is what I said there is, and I have it in my slides here there is an annulable method called select let me find it which is return all of the objects in this collection for which yielding it to the the object to the block returns true and I have it select yes so for each object in the collection if yielding that object returns a true value add that object to the collection so for instance if my collection is the range from 1 to 10 and my block is is the object odd that would return 1, 3, 5, 7, and 9 why would inject be bad in that case? inject is not bad in that case it's unnecessary and to the extent that it's unnecessary I prefer to use simpler constants you have to set up your collection no, because you're trying to return another collection so if you did this with inject you basically have to inject something like inject an empty collection into it and then accumulate the result the base case for inject is things like summing things up there are basically the question is why wouldn't you use inject here and I can give you two answers one is that in the case where the purpose of this method is to define an enumeration using another enumeration that is not the basis method each imposes overhead both conceptually and performance of this all of the enumerator methods depend on each and only require each they could be written in terms of each other it's easier and typically faster to write them in terms of each you made it seem like you generally dislike inject for the reason most people use it is that because it's just I dislike inject but I like reduce even though they're synonyms because I feel like the use cases for reduce it is completely appropriate to use reduce for things like summing all of the payments in this account together I feel like it's not appropriate to use inject when you really just want an accumulator array I'm sorry yes yes it is reduce yes I reduce is in a functional context what you would call a fold L which is to say that you start with the first object and you fold other objects into that object using some sort of composition method until you end up with one object that's reduce inject is a semantically vague which is why I don't like to use it reduce on the other hand has very well understood semantics and in some cases especially cases where your composition method for instance is the binary plus method is addition and you're summing that I think is a very elegant use case for inject or reduce but I prefer to call it reduce in that case because that is semantically closer to the operation I've been wanting questions? alright well I get to let you guys out very much