 Video equipment rental costs paid for by peep code screencasts. So I want to talk to you today about Ruby best practice patterns. And this is something that I spend a lot of time thinking about with my work with Ruby. And it's something that's helped me, I think, become a better programmer in general and not just with Ruby. So for those of you who are not familiar with the term, it's actually pretty simple. Ruby is Ruby. We all love Ruby. Best practice, there's a legal definition for best practice which has to do with doing work according to industry recognized best practices prevents being sued for liability or being liable for negligence. That's not really what I'm talking about here. What I'm talking about in the term, in the context of Ruby is I'm talking about just a set of techniques that experts currently recognize and use. And one of the key words here is currently because best practices change. They're really only our current understanding of how the best way to handle a given problem is. And a pattern is also important. A pattern is really just a decision that an expert makes over and over. It's something that's repeatable. And so if you put that all together, Ruby best practice patterns are just a series of techniques that Ruby experts currently use so that we can make good decisions when we write our code. And if these decisions we make are repeatable, that means we can keep making them because we often end up writing a lot of similar code. So how do they actually help us when we're writing code? Well, there are a lot of ways that you can optimize when you're writing code. You can optimize for performance. Oftentimes it is important. But I think one of the most important things to optimize for is how communicative your code is, how easy it is for other people to understand it. When I got to this point preparing this presentation is where I sort of had a sort of moral dilemma because it occurs to me that if you're writing code that other people can understand, other people can understand that code, which means that they can work on it, which means that you don't need to work on it, which means that they can replace you really easily. So the problem that occurred to me here is that if you're using these patterns and you're writing good code, then you're doing it wrong. And the reason for that is expendability. Which raises, I think, the most important question, which is how secure is your job really? Because studies show, this is important, studies show a strong correlation between the maintainability of code and the expendability of its author. Now I know some of you are visual learners. I have a paragraph. So how do we deal with this problem? I like to present, I think, a new paradigm that I think we can all adopt. It's called unfactoring from patterns. So what is unfactoring? It's actually quite simple. It's a process of taking well-designed software and through a series of iterative small changes making it completely unmaintainable by anyone but you. Big win, I think, really. So now that you've all bought into this, I know you're all wondering, how do I unfactor my code? Well, here's some things to look for. Look for code that's simple, communicative, that's flexible. Ultimately code that's maintainable, recognize that this is bad and then fix it. So what kind of code is this? Small methods, small methods are bad. Simple classes that don't do more than one thing are also bad. Dry code is bad and especially, I think, encapsulation and even more importantly, intentionally revealing names. If you understand what something is by how it's named, it just makes it really easy to maintain it and that is super bad. So looking through your projects, you may find some code that you want to unfactor. So how do we go about this process? The first thing that's important is to make sure that you have tests. Make sure that your code is thoroughly tested. That way when you are unfactoring away from this simple stuff, it will get very confusing for you, which is sort of the idea. But if you have tests and your tests pass, then you're fine. So once you have a comprehensive test suite, which you should because you're testing all the fucking time, then you can start making small changes. For instance, you can dampen your code. You can obfuscate your code. You can introduce coupling into systems that don't require coupling or don't have it in the first place. I'd like to introduce a new term. You can complexify your code. And in the interest of saving some time so we can all eat some lunch because I'm starving, I'd like to go over a few illustrative case studies because you have to have those in slides like these. So here we have some code from Capistrano. It's simple enough. This is a remote. It's the thing that you deploy to. And this is the deploy command. This is actually what it looks like in Capistrano. It's very simple. I think we all, can you all read that code? I think it's pretty clear as to what it does. It updates a repository cache and then it copies it. Yeah, that's far too easy. I mean, anyone here could look at this code, figure it out and then work on it. So that's a problem. So the first thing you want to do is want to complexify this code. Let's start by taking this well-broken out, well-factored method here using composed method pattern. So each of those two lines in the method call other methods that do the actual work, but they have intentional revealing names so that you can read at a glance and scan quickly through the code to understand it. So let's fix that. So we're going to take those methods and inline the code that those methods represent. And I think we're already moving in the right direction here, but if once I actually dug into this source a bit and it's not really that important that you read this line-for-line more that you understand the gist of what's going on here, there's some methods that do the same thing that were factored out and dried up. So we want to fix that. And finally, obfuscation is important. This goes along with the intentional revealing method names idea. And my personal favorite way of doing this is Pig Latin. So here we have a well-factored, well-written method that does something very simple. It's easy to scan for comprehension. And we can fix that. So I hope we can all move towards code that looks a lot more like this and a lot less like this because really your jobs are at stake here. I think is the important takeaway. So there's one other example I wanted to show you here. And this is from Webby, which is a very cool little static site generation tool. It's what I use for my blog. And this is a pretty simple method that pretty clearly does a few simple things. It imports some tasks, requires some files, captures some command line arguments. This is how Webby basically sets itself up when you run a generator and whatnot. And so it's pretty easy to read. It's pretty easy to understand. And we can, you know, unfactor that. We can replace init and this, this args with Pig Latin. We can, you know, move some things around to make it much harder to maintain. And I think that's the big win here, which is that if you unfactor your code, you can keep your job. And so that's actually all I want to say about unfactoring. So what I, what I really want to talk about here is not unfactoring, because obviously unfactoring is not really a win. Because it turns out that most of the time that you spend on your own code, you spend maintaining existing code, right? You know, you write something once and then we read it dozens, hundreds of times in the future. So when I say that writing code for maintainability and for understandability is important, that you should optimize for that, that's what I mean. Because 90% of the time you spend on any project, on any software project, is spent maintaining existing code. It's not spend adding new features. So the patterns, there will be best practice patterns. A lot of these are taken from a book by Kent Beck called Smalltalk Best Practice Patterns. How many of you guys have read this book? How many of you guys have heard of this book? Lots, almost all of you, that's great. So I actually learned Smalltalk so I could understand the examples in that book a few years ago, and it proved extremely important in my development once I understood those concepts. And a lot of them I think are things that we mostly do without thinking about. How do I name variables? How do I write methods so that they're well factored? How do I name classes? How do I initialize complex objects, things like this? We pretty much solve these problems on a day-to-day basis in our own code. But the point of having patterns is that if you make a decision repeatedly, you should be able to make it better the next time than the first time you made it. So it's all about identifying repeated decisions that you make, finding a pattern that encapsulates that, and then applying it in the future. And so one of the things that's important to remember when you talk about patterns is the context that they're in because every problem is going to be a little bit different. Every problem you solve is going to have tensions that draw you in one way or another. Sometimes what's important is performance. Sometimes what's important is having a flexible API. There are a lot of different tensions each time we solve a problem that we have to consider. So each pattern is really only relevant in the context where you're trying to solve a specific problem. The idea is that most of these tensions are the same from decision-to-decision. So if, for instance, I want to decide how do I name a variable properly? How do I give it a name that will help me understand its function? Then that decision is pretty much the same every time you make it. You don't want to name it after its implementation. You want to name it after its intention. What does it do? Not how does it do it? And if every time you name a variable or name a method, you make that decision consciously, your code will be better in sort of small incremental ways that add up in the end to more maintainable code. And so that's really the heart of patterns. And I actually don't really want to show you this talk because it's obviously not the real talk. I really want to get to some actual patterns. I want to show you guys some examples in the wild of ways you can use patterns to make your code better. So let's start out here with one of the ones that I pretty much use every day all the time. It's called Compose Method. And the idea of Compose Method... The idea of Compose Method is basically that you have a complex method that does more than one thing and you want to divide that up so that it's easier to understand, it's easier to read. And the way you do that is you divide it into multiple methods where each method performs one simple task. Each method has an intention of revealing a name so you know when you see it being called, why it's being called and what it should be doing. And then complex methods should be composed from these smaller methods and built up. So instead of having a 20-line method that does five different things, you have a five-line method that calls five smaller methods that each do one thing. And it's much easier to read, to scan for comprehension when you're trying to understand, sort of in general terms, what this code is doing. And it's also easier to understand in detail when you see each specific method because the context of that method is smaller and it only does one thing. So as an example, and this is again from Capistrano, this is how you would get from that unfractured state where you have this deploying method that does two different things. I don't really know what those are. I can't scan this. I'm pretty sure you guys probably are having trouble reading it. I can't really scan this for comprehension. I can't look at this in a second and say, okay, it's doing this and this. I have to sort of read it line by line, try to process each of the different pieces. And so we have two different things that are happening here. One is... Okay, I actually have to read this to figure it out. One is, let's see, repository cache, source sync, check out. So it looks like it's checking out repository cache. Okay. Then the next is... Let's see, configuration command. So I don't actually know really what that's doing, but if I refactor it to a compose method and I look at this, then I can tell exactly what it's doing. It's also easier for me to now unit test each of those simple methods. And so that is probably one of the most important refactorings that you can do based on patterns. And another one that I think is a very powerful one in Ruby that I am seeing a lot more of, that I really appreciate is the execute around method. And that is taken originally, I guess, from the small talk book, but it's actually implemented in Ruby itself, for instance, in terms of file open and close if you use a block. I'll get to that in a second. So the question is, how do I ensure that things happen together? I want things to happen. I want to ensure that something happens and then something else happens. So the way that you make that happen is you write a method that takes a block and then inside that block, you ensure that those things happen and you can yield in between. So for example, I want to open a file and ensure that it closes. Now, I don't know how many of you come from, say, a C background or a background where resource allocation is something you actually have to think about and you have to think about the allocation and the destruction of resources and reclaiming them in that. So in Ruby, we don't usually have to think about that, but if you open a file and you forget to close it, then that's memory leak and you want to avoid that. And so the better way to do that instead of opening the file, doing things and then closing it in the main context, is to actually have a block where within the block, the file is open. You do whatever you want to do with the file in the context of that block and then closing that block, ending that closure, actually closes the file. And so I think the best way to demonstrate this is to use the Rubinius implementation. And here it is. This is IO file is a subclass of IO. This is IO open and it does exactly that. It opens the file and then it processes it with the yield and then it ensures that it closes. So even if the processing of the file throws an exception, the file will still close when the block closes. Another example of that would be after filters in Ruby on Rails. In Ruby on Rails, you sometimes want something to run both before an action is called and then after the action is called. And so Rails has a simple pattern for that which uses the execute around method, which is the around filter. You say, call this around filter. The log would debug before happens before the action is called. The yield essentially calls the action and then the debug happens after. And so you can use that instead of both the before filter and an after filter when you want to make sure that two things happen around yielding this action. And here is one that was touched on with Ruby 1.9. 1.9 has an implementation of this. Rails also has an implementation of this. I want to be able to send multiple messages to the same object. And I think Bruce mentioned, Smalltalk has the concept of a cascade, which is that you can specify a receiver, call a method, then with a semi-colon you can chain more methods that will get called on the original receiver. Ruby doesn't have that. It doesn't have something that's almost as good, which is being able to yield to the object inside the scope of a block. So as an example, Repaginate, which I'm sure a lot of you use for pagination in Rails, can paginate pretty much anything. And so it could, when you create a Repagination collection, you could do it like this. You could create this post-collection and then you could do some stuff to it, and then at the end you can return it. But the issue here is sort of a life-cycle problem, which is I don't know when this post-collection is really ready to be used. It turns out I can't really use it until all of this stuff happens. But there's nothing in the code that tells me that the post isn't ready to be used after it's been replaced with all that happens in the middle. If you change that to do the way Repaginate does it, then what you're actually doing is you're doing all of that inside the context of a block. So I can see when I scan this method I can see that when the block closes or I can't dig into this block and say, okay, get me the post object after it's been replaced with the results. Because the block is clearly telling me that it's only ready to be used when the block closes. And Repaginate has a pretty simple implementation of that. It creates a new pager, it yields to it, and then it returns it. Rails has returning that method could have been written instead of defself.create and then pager.new it could have been returning new pager and then yield or block call rather. And likewise, Ruby 1.9 has tap and so that method could have been written Repaginate collection new.tap and then you yield to the block or you yield to inside that tap block. And so that's one of the ways that you can use blocks in Ruby as a pattern to help you understand the context of the closures around creating a resource when it's ready to be used, that kind of thing. So here's one that's a little bit more complex that I don't use as often, but when I do find a chance to use it, it's really helpful to me. And this is a method object. And the context where this is useful is if I'm calling a lot of methods with the same arguments over and over and over again, if I'm passing the same parameters to multiple methods, what this really means is that there's states that's encapsulated in those method calls that I'm not aware of, that my domain model isn't aware of. And so usually when we think of classes, we think of them in terms of state and behavior. And usually that state is things like the contents of a blog post, the contents of a transaction, you know, the amount of money in your account, but that state can also be things that really are just a state that methods require parameters that they need. So if you think of a class as really just holding the execution of a method, you can answer the question which is how can I write a method where lots of these lines of code share the same parameters. The way you do it is you use an object to represent that method. And in that object, the instance variables will be shared between its own methods, the instance method is in that object, and then you can use compose method to simplify that construction. So as an example, this is a method that creates a .file, creates a graph, or creates a .file based on a graph. And so it does a few things, it grabs some things from the graph and adds them to the output and then it returns the output. But we can see that we keep passing in the same graph, we keep passing in this same collector variable, accumulator variable. And we don't need to do that, it can be done like this. This output generator class isn't a class that holds state as much as it is a class that holds a behavior, and then the state necessary for all of those behaviors. And the way you implement that is pretty simple. You just take those methods that were being called with the multiple parameters being passed in, you just put them in the class itself, the output generator, and then they have access to all of the local state inside that object. So I think hopefully I've convinced you guys that patterns are useful, I hope you write better code. If I've actually convinced you guys to start unfactoring then I'm in trouble because I see a lot of unfactored code and it's a real pain. My real goal is to I guess Z would say take rails out of the gutter or the ghetto. And I think I'm starting to understand what he meant by that because I see a lot of code when I work at hash rocket we do a lot of these rescue missions where we're taking on other people's code. And without naming names most of it's crap. I forget whose law it is but 90% of everything is crap. Sturgeon's Law, it applies to most of the code that we see. And if developers start applying patterns, start being I think more deliberate about the way that they code and more insightful into their process then that's going to make my job a lot easier. And I'm all for that. So my real hope here is that we can get rails out of the ghetto that we can all start writing beautiful elegant code that's simple that's easy to read, that will be easy to maintain down line in the future when it matters because it's easy to write code. It's easy to get a computer to do what you want it to do but it's a lot harder to write code that other people can understand. I think it's really important if we start having this conscious decision in our minds that I want to write code so that other people can read it so that other people can understand it then that will help us write code that is more maintainable for ourselves in the future more maintainable for other developers that take it on that contributes a lot more value to open source where literally everyone is going to be reading your code. So that is my real goal here. So how can we learn these patterns? I think it's important to remember that each one of these patterns only solves a small part of the problem of writing good code. And patterns I think design patterns is an overloaded term. I'm thinking most of you are probably familiar with the Gang of Four book and the patterns in that book are much larger in scope and in my experience much harder to apply on a day-to-day basis. I may design a piece of software that has one pattern out of that book maybe but the patterns that I'm talking about are something I apply on an hourly basis. Every time I name a variable, every time I write a method every time I determine if I need a new class or not. These are patterns that I'm constantly applying when I write my code. So I think it's important to remember that these patterns really are a small scale of things. They're small chunks that if we just keep them in our minds while we're writing code they'll help us all the time and not just a few times in the system. Then there's also Martin Fowler wrote a great book called Patterns of Enterprise Application Architecture which is where Active Record comes from. It's where Datamapper comes from. It's where a lot of the pattern-based libraries that we use in Ruby actually come from. I'm guessing almost all of you probably use Active Record. Whether you like it or not that's an implementation problem. The actual pattern is pretty awesome. So it's a lot harder to apply those patterns than it is to come up with them because the real challenge that I see with these larger scale patterns is that they're very good at solving the domain that they're built to solve but actually implementing them is the real challenge. These are really implementation patterns. These are patterns that you use to implement things, to implement other things, to implement designs. The patterns that you use constantly. So it's important to understand that you're not thinking about large scale patterns that govern the architecture or the scale patterns that govern the naming of variables and things like that. Which means that these patterns are almost always useful. It's also, I think I mentioned this before, it's important to remember that each of these patterns is relative to the context. Sometimes it's really important to have performance over communicativeness. Sometimes you want to optimize for performance even at the sake of pessimizing for the maintainability or the communication value that you're making a decision that has tradeoffs, that you're trading maintainability, you're trading readability, you're trading understandability for performance and you're doing it for a specific reason in this specific case. It's important to understand that most of the time the tradeoff you want to be making is towards communicative code. It's towards maintainable code. Only sometimes in certain situations where performance is really critical, you want to make the trade in the other direction. And there's a lot of good Ruby out there. I know I said that most of Rails is a ghetto, but especially open source. Most open source projects get a lot of eyes on them and a lot of the code in there is well written. I used examples from Capistrano, which I think is a very well written, well designed library. I think the code in detail is extremely well written. It's extremely easy to read and understand. And so trying to find libraries like that out in the wild, gyms that maybe you already use on a daily basis and trying to learn from example by trying to read their code and understand why they made the decisions they made will help you be able to find those patterns and then fundamentally what you have to do is you have to try them. You have to apply them in your own code. You have to look for excuses to start using these patterns. It may slow you down at first. When I was reading this small talk book, I basically kept it open and every time I would write something new, I would try to find a pattern that would help me write it better. And this made me a lot slower for a week or two, but in the end it turned out to be a big win because now that once I started internalizing these patterns I didn't have to go look them up. They just came to mind immediately and I was able to apply them. So that is pretty much all I have. Thank you guys. I hope you enjoyed the unfactoring part. I hope you don't actually do any of that. So I'd love to open this up to questions about patterns. I know that patterns are somewhat of a hot topic right now in best practices. I think a lot of people have a lot of different opinions, but that's why I'd love to take some questions and maybe open up a dialogue. Any questions? Yes. Specific to Ruby itself? I think Ruby is definitely a very idiomatic language and I actually debated myself between whether these should be Ruby best practice patterns or whether they should be Ruby idioms. I think idiom may actually be a more accurate term because Ruby does promote coding in a certain way. Ruby is a very elegant language and a very beautiful language and it's very easy to write good Ruby, but the way you would write good Ruby is to write good Python, for instance. So I think that a lot of patterns in Ruby are specific to Ruby, which is actually why I think it's important to make this distinction with Ruby best practice patterns, even though there's already the Kent Backbook, for instance. So you're talking about how we use blocks to do, like, an execute around method. Sure. Blocks are very powerful in Ruby and less powerful in other languages, so you want to take advantage of these features in the language, definitely. I hear you're writing a book. I am writing a book for Edison Wesley called Ruby best practice patterns with Kent Back. And we did actually talk about whether we should call it whether we should use the term pattern or idiom. And we decided to use pattern, I think mainly for the heritage of the original book, which is one of my favorite books of all time. I'm looking forward to that book. It should be out early next year. But in the meantime, I would invite you all to at least take a look at the Small Talk Best Practice Patterns book. Small Talk is a pretty easy language to at least understand the syntax of, and I think that really helped me out when I was learning, so I would recommend it. Will there be a beta for that book? I'm sorry? Will there be a beta for that book? I don't know. I'd like to. Any other questions? I think they're all hungry. All right, break for lunch. The lunch is, you can bring your plates in here and go to and eat. We do have that bar room over there.