 We are starting off our technical program right now, and our first speaker is my fellow Ruby Rogue Afdiegrim. He was in Pennsylvania. He did a really great e-book in the last year called Exceptional Ruby. He did some talks in that last year. I started doing that talk at RubyMales and decided I wanted to speak here because he has a way. So this morning he's going to be showing you lots of ins and outs of Ruby with a talk entitled Code to Joining. Welcome Afdiegrim. People schedule appointments with me and with them. And I get to pair up sometimes multiple times a day with people from all kinds of different levels of experience and with different problems in front of them. And I have the privilege of getting to hear this. A lot. That's so cool. I didn't know you could do that. I love this. I love it. It's so great to be able to bring that to people. Ruby makes me happy. This programming language is designed to make programmers happy. And after all these years of using it, it still finds ways of making me smile. Something else that makes me happy. Postcards make me happy. So I'm writing this book called Confident Ruby. And I decided to do something a little different this time around. I decided you could pay me 25 bucks for the book or you could send me a postcard. And so I have postcards now from all over the world. And I love this. And the stuff that people write on them is just amazing. It just floors me. And so postcards make me very happy as well. So here's the plan for the next 28 minutes. I thought we'd take a random walk through the Ruby language and standard libraries and talk about some of the idioms and tools in there that bring a smile to my face. And since I suck at coming up with illustrations for talks, I thought I would just throw in some of the postcards that people would send me instead. Let's talk about splats. The splat operator, the star, the asterisk in Ruby. If you have something, a method that returns multiple values, returns an array of values like process.way2 returns both the process ID and the process status. And if you want to sort of destructure those into two different variables, you can use the splat operator and it just, you know, it splats it out, it structures it out into the two separate variables. It's very convenient and it's almost like having multiple return values. And there's actually, for some cases, there's implicit splatting. So Ruby's smart enough to say, okay, it looks like you want to splat this return value out. So I'm not even going to make you put the star there. I know what you're doing and it works. It's great. Let's say we have a method, we'll call it sendRequest, which we want to return multiple values from. We've got both a status code and a message. Now, we have some client code, which would like to use this as a multiple return value kind of method. It wants to immediately splat it out into separate variables and use those. But we have other client code, which would like to use the return value as an object, which it can maybe pass around to other methods easily. And use those result values as attributes on the object. Well, how can we satisfy both of these? Turns out it's not that hard. What we can do is first we can create a struct for those return values. We've got our code, our message, and the struct. We can instantiate an instance of this struct with the values. And of course, as a struct, we can access those as attributes. Code, R.code, R.message. But we can also splat that struct out. And it just works. It splats out into separate variables. Now, there's one little problem. Remember the implicit splatting from before? Well, this does not support the implicit splatting out of the box. When we try to do that, it doesn't quite work. If we go into that struct definition, and we alias 2A, it already has a 2A. And we alias that's a 2-ary, which it didn't have a 2-ary before. The 2-ary, turns out, is a signal to Ruby that implicit splatting is possible. So once we do that, we can instantiate this response object. We can splat it out into multiple variables. It just works. So in our similar question method, we return a response object that we create from the code and message. Now the client code that wants to splat that out immediately into multiple variables can do it. The client code that wants to pass it around as an object can do it, can have that too. So this gives us a way to have multiple return values from a method or a single result object from the same line of code. Magic. It makes me happy. Who knows about YAML Store? Raise your hand. Cool. I'm going to be introducing a lot of people to this today. YAML Store is part of the standard library. It is a very simple file-based persistence mechanism that Ruby provides for you. And here's how you use it. You instantiate a repository. You give it a file name. Then you open up a transaction block. And inside that transaction block, you can use the repository basically like a hash. It has keys and values. And what I'm doing here is I've got some post objects, because everything's a blog example in Ruby. And I've got a post key, and I'm putting an array in there and I'm appending some posts to this repository. When we look at the data that puts out, that puts in that blog.yml file, it says really readable YAML, which very clearly reflects the structure of the objects that we put in there. Now what if we have a slightly more complex object structure? So let's introduce a category to these blog posts. And we're going to have two blog posts now that are both part of the food category. What's that going to do in the output? So here's the output that's generated. We can see a lot of the data is the same. We've got our two posts in there. In the first post, we've got a category object nested under it. And it's got that funny ID in front of it. And then it's got the information about the category. Then in the second post, it's got a category as well, but it doesn't repeat the category object. It just has a reference to that previous category object. So it's very smart about dealing with objects that reference other objects. It's not going to write an object more than once. It'll just put the references back. So objects can reference each other. It works out very well. So this is pretty awesome. But it's also pretty slow because it's reading and writing YAML all the time. And it turns out that there's another library called Pstore, which actually YAML store is based on Pstore. Pstore came first. Pstore uses Ruby's binary marshalling format. So if you have trouble with the performance of YAML store, you can just drop Pstore in its place and use that. You won't have nice readable output, but in some very important measurements I did, it turns out to be much, much faster. So this is not something that you're going to be putting on your web server and serving out pages on. But if you have some kind of like local command line application, this is great. It gives you an incredibly simple hash-like persistence mechanism that you barely have to think about. It supports complex object trees. And oh yeah, one more thing. It's almost equal. This method is very simple. It just yields a series of names one after another. This is a straight line method. There's no moving or anything involved here. So a straight line method. We can call two enum on that and give it the method name. And we get this enumerator thingy back. If we call two a on that enumerator, what do we get? We get an array of the values that this method yielded. So what this enumerator did was it turned our method that yields into an iterable object problem recently. I had a program that had config files. And I wanted to treat them kind of like rake treats its config files. So I had these files called .rc. And I wanted it to like rake. I wanted to search up the current directory hierarchy. So if it didn't find one config file in the current directory, it would find one in the parent directory or in the grand parent directory. But not only that, I wanted it not just to find one, but I wanted to find all of them all the way up to the root and then basically merge them together. Turns out there's a method in the standard library that got me most of the way there. The path name library has a method called ascend. So you can call ascend on a directory. And it yields once for the current directory and then once for the parent directory and grand parent directory and so on up to the root. So this was great. It got me most of the way there. But this wasn't exactly the way I wanted to iterate because I kind of wanted to collect an array along the way if I found one of those config files. So here's what I did. And we'll go through this line by line. I took that current directory. And rather than just saying got ascend, I turned the ascend method into an enumerator. So now I had an unhitterable object over the ancestor tree of this or the ancestor path of this directory. And now that I had an enumerator, I had all these wonderful enumerable methods available to me. And the one that I wanted to use was each with object. So I said each with object, I passed in an empty array and then I went through that, I iterated through that ancestor tree path and at each point I checked to see if the config file was there and if it was, I added it to the array. And then this whole log returned the array, it worked out great. So an enumerator and two enum, you can turn any method that yields into an iterable series and it makes all the power of the enumerable available to that series. This is awesome. It makes me happy. Let's talk about break. What can we say about break? It's a key word. It breaks out of loops. What do you do? Well, let's take a look at that method we introduced earlier again. Remember, just a straight line method, no looping or anything, it's just yielding names one after another. What if we introduce, what if we use that method and we pass it a block which will break after two names? So you can see the output at the bottom, it gets two names and then it's done. What if we just do this? Let's take a look at that. We started going down, executing this straight line method. We got down two lines into the method and then we forced an early exit from this method and we did it without a return, a throw, or a raise. Might raise a question in your mind. That's kind of interesting, but it kind of sounds kind of dangerous too because what if that method had some important clean-up that it needed to do at the end in an inshore block? Does that mean it would just be front of way, it would just be ignored? Let's try it. Here's a version that has an inshore block which always puts out a last name. Put the exact same block into it, now our output has three names. So what just happened? We forced an early exit from that method in the right and middle, but then Ruby jumped down to the inshore block, executed that, and then finished breaking out of the method. And this is pretty cool because what this means to me is that Ruby has my back, even if I'm doing weird things with break, it still has my back. It's going to make sure that stuff that I put in place to clean up after myself is going to be called. What if we wanted to capture a particular name out of this iteration? So we have a regular expression. We want to capture the name, the first name that begins with s. And we could do it like this. We could set up a result variable that starts out as nil and then we could pass this thing into our block and when we find a match, we assign name to the result and then we break out. And this works, but it's kind of flunky. Another way to do it. It's different here. I am, this time, I'm passing a value to the break keyword. How many people know that you can pass a value to break? A good amount of people, that's awesome. What does this do? Not only does it break out in the middle of execution, it effectively overrides the method's return value. So I have forced this method to return the thing that I'm interested in, not the thing that it's interested in returning. Or they return by default. Let's take a look at maybe a more useful example. Let's say we want to search through the lines of a file for a particular string. When we find that string, we return it. We find the matching string, we return it. And then we're done. And this is a classic application of, you know, you typically use, like, a detect for this. But there's another requirement here. We also don't want to do this forever. If it's a really long file, we don't want to just keep searching through it. We want to give up after the first hundred lines. Here's a way we can do it, using a break with a value. We take that file, we get an enumerator over its lines, like a length of lines, then we call detect. And at the bottom of the detect block, we have our usual detect logic where we say, you know, here's the test of whether the line is matched. And if the line is matched, then it'll return the mapping line, which is what we expect of detect. We'll also have this break line in there, which checks the line number count and breaks out early with this special line not found value if we pass that max line count. And as a result, we go through the file, if it doesn't find that matching string in the first hundred lines, rather than having to have some logic later to replace, you know, the nil that we got out of detect, we've forced that default to be this special string line not found that we wanted to use. Let's talk about subclassing modules. Let's take the example of a really basic role of that game. We've got characters and they've got character class. They've got a character race. But here we're setting up a particular character who is a human wizard. So we've got a human race character, a wizard class. And here's what we'd like to happen. We'd like the character to have some attributes of its own. We'd like it to then delegate attributes that it doesn't have defined on itself to either its class or its race. Here's one way we can do it. Use forwardable. We can say we could extend our character class with forwardable. And then we can define some delegators. So we delegate the string to race. We delegate charisma to the character class. This works fine. But then one day we decide we want to add a new attribute to the race. And then after we add that, we have to go back into our character class and add constitution to the list of delegators for race. And we realize that every time we add a new attribute to either a character class or a character race, we're going to have to add another delegator. And that kind of sucks because that's repeating ourselves. That's knowledge in two places of the same thing. Every change has to be made twice. We might briefly consider using symbol-delegator because symbol-delegator delegates any missing message to a delegate object. The problem here is that it's just one delegate object and we have two things that we want to possibly delegate to, either the race or the class. So here's the way we can solve this. We create a new kind of module by subclassing the module class. We give it a custom initializer. It's going to take the attribute of the object that it should be delegating to. And we're going to save that off in an instance variable. Then we're going to call the base initializer for module, which if you've ever done module.new, you know it takes a block, which is the implementation of the module, and that didn't all fit on this slide, so you're going to go to the next slide where we are defining a method missing in that body. Let's go through that bit by bit. First we find a target of our delegation. So we send that attribute name, like race or class, to self. And that gives us a concrete delegation target object. Then we ask that target if it responds to the missing message. If it does, we forward that message on to the target along with its arguments. If it doesn't, we just pass it on up. For general readability, we also add a nice 2s message to this. So to use this, we go back to our character class and we include instantiations of this new kind of module. So we are creating modules on the fly here and one of them is a delegator module to race and one of them is a delegator module to character class. And if we take a look at the player's class ancestors, we can see very clearly what's going on here now because we have defined that nice 2s method. The message, when a message is sent to this object, it's going to start out looking at itself, character, its own class. And then it's going to look at the delegate module for character class. And then it's going to look at the delegate module for race and then it's going to go on up the chain to the other ancestors. And here's how it works in practice. We have our player character. It has its own attribute name when we call strength on it that's delegated to a race when we call charisma on it that's delegated to the class. And we've defined kind of a chain of responsibility here. We start with self, then we start with, then we go to one attribute, check if that attribute supports it, we go to another attribute, check if that attribute supports it, and then we go on up the chain. And so we have basically defined a new kind of delegation mechanism here. But we hooked it into the Ruby, the standard Ruby message searching system. So by subclassing module, we can create a new kind of module, we can add state to the new modules that we created. And this, as I said, this enables us to do crazy things like enable completely new types of message delegation. This is awesome. This is the kind of thing that when I realize I can do this, it just makes me grin. Now my favorite idiom of all in Ruby is minus one, maths is nice, so we are nice. Sometimes we're not so nice. Sometimes we're not so happy. Maybe technical debt is getting down. Maybe community drama or a passionate community, any kind of passionate community of craters is going to have drama. Maybe the drama is blowing you out a bit. What do you do? What do you do? I say to balance out that negativity is essential to practice joyful coding. Well there's no metric for joyful code. The only thing that makes code joyful, the only thing that makes it delightful is the fact that it is shared with someone else. So if you want to feel good about your craft again, because you're feeling down and you want to pick me up about the thing that you do every day, pick one person, one person that maybe knows a little bit less than you do about some area and give them a wow moment. Show them something awesome. I promise you will feel better. So I want to thank you for allowing me to increase my joy by sharing these items with you. And I hope that I've inspired you to turn around and increase somebody else's joy the same way. Thank you very much. Great job by the way. So a question where when you return a keyword, a value after break, what happens if you have a rescue also in the same piece of code? Will the value that you pass to break return or can you change the behavior by in the rescue close returning something else? Well, it's going to ignore the rescue clause because it's not an exceptional return. So it's going to pass by the rescue clause because you would have to raise an exception that matches that rescue clause in order to... Rescue? I mean, ensure? No, and ensure. Okay, so I believe... It's a great question. If you just have a value in that ensure clause, I believe the break should override it. However, don't quote me on that if you put an explicit return in your insured clause. And this is sort of something that's a whole other area that I got into in my exceptional talk. Do not do put an explicit return in insure. Weird things happen. It's a good way to accidentally throw away exceptions. Could you go over why you used to find method in your method-missing thing in the magic methods? Why did I use define method? I used define method because I had some state... So I saved off the attribute name in the initializer, but it turns out it's somewhere between hard and impossible to actually get at the modules, instance variables from methods defined in that module. Modules, you know, it's got plenty of access to the instance variables of whatever object it's included in, whatever class it's included in. But try to get at the instance variables of the module as another story. So I happen to have... I happen to have that attribute as a parameter of a method, and so I'm basically closing over that. I'm making a closure over that variable and keeping it around that way. That's how I get access to the attribute name inside that attribute. KeyStore and YAMLStore are really awesome and cool tools. Have you ever came across a simple story that lets you do a range on the keys? If your keys are a timestamp, you want all of the values since a certain thing? There's really no... Are you talking about querying? Yes. So, not off the top of my head. There's no provision for querying built into YAMLStore. It's just... Here's a tree of objects. You can go through it any way you want. Actually, one thing you could potentially do is you could actually... Since anything can be a key in a Ruby, anything can be a key in the hash. You could make a range. You could make last week one of your keys and this week one of your keys. I don't know. You could do some crazy stuff, but I'm not sure how well it would work. This is awesome stuff, but it seems like we're playing in exactly the area that Charles was addressing yesterday as being painful to optimize around. Yes. Yes, that was one of my goals, giving Charles anything. Okay. That's basically the main question is are you giving Charles on speaking terms? Possibly not anymore. Because the module subclass that you showed looks exactly like HyperCard's containment style chain responsibility delegation, so I just looked at it and said, oh yeah, cool. Only vaguely related to that. I know we talked about the self system in the past, and if anybody can show me an elegant way to do something like this only to get self-style delegation where self is always self, which I don't know a better way of explaining it. When you delegate to another object, self is still the same object instead of that other object. I would love to see it because I still haven't come up with a clean way to do that. Okay, we're done with questions. We're going to do a break and we'll be back. Thanks everyone.