RR Book Club: Practical Object-Oriented Design in Ruby with Sandi Metz
04:51 - Please take part in our survey: Best of Ruby Rogues 2012
05:03 - Next Book Club Pick
06:09 - Sandi’s Writing & Speaking Processes
- Sandi Metz Talks
- Ratio of prose vs code samples
14:07 - Parallelism between the process for writing software and the process for writing prose
17:23 - The Flow of POODR
21:57 - Design
Understanding Concepts and Explaining them to Others
- Rules and Using Best Judgement
- Recipes are like Coding
34:00 - Practical Prescriptions and Visualizations
41:20 - Beyond POODR
- Objects on Rails Sponsor Edition
- Rails App Advice
- Best Practices in the Rails Community
45:11 - Rails
51:03 - Frameworks
54:40 - Object-Oriented Design, Dependency Injection, Hiding Instance Variables vs YAGNI (You Ain’t Gonna Need It)
01:00:45 - Inheritance
01:06:25 - Chapter 9: Designing Cost-Effective Tests
- Testing Private Methods
- Integration Tests
01:17:46 - Sandi’s Programming Rules
- Breaking the Rules vs Not Breaking the Rules
01:35:28 - Too Many Small vs A Few Big
01:43:50 - New Media Expo
Concurrency and Celluloid with Tony Arceri
DAVID: I tweeted this morning. I’ve gained seven pounds since I got a Fitbit for Christmas. This thing clearly does not work. And somebody wrote back and said, “You have to shake it.”
[Hosting and bandwidth provided by the Blue Box Group. Check them out at BlueBox.net.]
[This episode is sponsored by Jet Brains, makers of Ruby Mine. If you like having an IDE that provides great inline debugging tools, built-in version control and intelligent code insight and refactorings, check out Ruby Mine by going to JetBrains.com/Ruby.]
[This podcast is sponsored by New Relic. To track and optimize your application performance, go to RubyRogues.com/NewRelic.]
CHUCK: Hey everybody, and welcome to Episode 87 of the Ruby Rogues podcast. This week on our panel, we have Josh Susser.
JOSH: Hey, good morning everyone. Happy New Year!
CHUCK: James Edward Gray.
JAMES: I’ll be your cyborg panelist for this episode.
CHUCK: David Brady.
DAVID: Happy New Year, everybody! Well, I guess, last week was when you listened to me anyway. Happy January. Hi!
CHUCK: Avdi Grimm.
AVDI: Hello from sunny Pennsylvania. And if I sound a little funny this week, it’s because I’m presently coating myself in sand trail in order to assume an immortal pre-worm form.
CHUCK: Awesome. I'm Charles Max Wood from DevChat.tv and I'm working hard on RailsRampUp.com, so go check it out. Katrina isn’t here this week. She’s off chasing reindeer in Norway. And we’ve got a special guest, and that’s Sandi Metz.
CHUCK: So, I'm sure it comes as no surprise to anybody that we have Sandi here since she wrote the Book Club Book: Practical Object-Oriented Design in Ruby.
DAVID: I'm surprised she agreed to come.
SANDI: Withall the hype in the Fall, how can I resist?
JAMES: Actually, I'm pretty sure if you listen to our episodes over the past several months, almost every time I’ve had to say the name of the book, I think I’ve gotten it wrong including in last week’s episode. So, yeah.
SANDI: Just say POODR.
JAMES: Well, the problem is I can never remember it. Like, what the P stands for. I think I’ve called it Pragmatic, Practicing, whatever. And then, I can never remember if it’s ‘in Ruby’ or ‘with Ruby’.
SANDI: You know, I can't remember that part myself. [laughter]
CHUCK: You know, I keep mixing it up with the GOOS book. And so I'm like, ‘Practical Object-Oriented Software Guided by…’ No. I was always like practicing this morning so I could say it right.
JOSH: I just pretend that I'm David Brady and call it POOPER. [laughter]
SANDI: Yeah. Whoever put that on Twitter, the person who said, “Practical Oriented Programming.” And then someone said, “POODR, really?”
SANDI: I have a friend who’s five years old. He refers to his dad’s laptop as ‘The Pooder’.
SANDI: And so, that’s how I remember.
CHUCK: Yeah. So, real quick. I know most of us have met you at various conferences and things, Sandi. But for our listeners who may not have had the pleasure, can you just introduce yourself really quickly?
SANDI: Sure. I'm Sandi Metz. I'm a woman of a certain age. So, that means I've been writing software for longer than most of you have been alive. I don’t work for a startup. I don’t work for a consulting company. I actually sit at a desk and write code for a living and I've been doing that for 35 years or so. The first significant number of those years were long enough ago that it was COBOL. And then, I fell into SmallTalk. So, I wrote SmallTalk apps for 12 or 13 years. I had a little brief segue into Java and then was rescued by Ruby in the mid 2000’s. And then, I got caught at a conference. I got overheard in a hallway rant and some people started trying to get me to write a book which took a while. And then, I wrote a book. So, the reason I'm here today is because I've been in a cave all my life writing code but some folks made me come out of that cave a little bit. And now, I have to talk. You guys aren’t strangers fortunately. But I have to go to conferences and talk and get out. [crosstalk]
JAMES: Was it them convincing you to write a book that took a while or the writing of the book that took a while?
SANDI: Both. It took about three years for me to really write it. And then, it took two years overall to actually get it written. So, it was an extremely long and painful process.
JOSH: And everyone that has ever written a book knows what that’s like.
SANDI: I can recommend it to you all. [laughter]
DAVID: We just have some business to take care of and then, we can jump back in on this. The first thing I want to announce real quick is that we have the best episode survey that you can get to at RubyRogues.com/Survey. So just go in there and let us know which survey was your favorite. And James also has an announcement for us.
JAMES: Yeah. So, it’s time for another book. And we held the book on Parley, gave several options and the one that rose to the top of the pack is ‘Patterns of Enterprise Application Architecture’ by Martin Fowler. I actually got that name right because I looked at the front of the book when I said it. So, that’s the book we’ll be reading next. It’s pretty thick. But in the intro, he says really that the first part is the part you read and then the back half is kind of a reference if you want to thumb around. Or if you want to read that too, great! We’ll probably give a couple of months and discuss it, probably early March. So, pick that one up and get started.
DAVID: That’s where we actually find out [audio distortion].
JAMES: Yes, and more. You’ll be surprised when you crack it open and read through. This book is 10 years old. And when you crack it open and read through just the pattern games, you’ll be like, “Oh my God! This is the Rails book.”
DAVID: So, dated is what you mean.
JOSH: Before we get into talking about the contents of the book, Sandi, I wanted to ask you about the -- we’re talking a little bit about the writing process and how excruciating it was for you. I've seen you speak a couple of conferences now and watched a couple of your videos. And to our listeners, if you haven't watched -- if you haven't gotten to see Sandi speak in person or haven't watched one of her videos, go watch her videos because she’s a really amazing speaker. And like everything she says is really carefully thought out. She’s definitely not up there riffing extemporaneously like some of us do on stage.
JOSH: But Sandi, I wanted to ask you about the interplay, the interaction of the book writing process and the speaking process. Because I assume that there was some period of time when you were talking about this material when you were still writing the book.
SANDI: Yes. The first thing I would say is that talks are equally painful. Talks take a long time to put together.
JAMES: Yeah, Amen!
SANDI: Right? And like, any talk -- if you’ve seen a talk online that I gave, I would say that the average prep time for me for a talk is everyday for up to two hours for about three months. Now, I know that that probably marks me as someone who’s painfully incredibly slow like, clearly people give good talks who don’t have that much -- don’t have to put that much effort into them. But the talks are absolutely crafted. Like a lot of people say, “Oh, don’t worry. You’ve done everything you’re going to say.” I can promise you that when I give a talk, every word is scripted and every slide change is marked in the script. And so, when I get into trouble with my talks is when I wander, if I started like making stuff up, I get off-track. And so the talks -- it was very interesting while I was writing the book and making talks about the book content - how different the mediums were. It’s so much easier for me to explain things if I can draw a lot of pictures. And in a book, you can't really like put a slide up and you make a tiny little change on the slide and then make another little change on the slide and then make another little change on the slide because people will just feel cheated when they’re reading a book, if you have 10 pages with the same diagram with slight differences on it. And so for me, that was the huge benefit of giving talks, that I could draw a lot of pictures that had very tiny differences in them; where in a book, every time I want to explain the same concept, I had to just use words. And that made it particularly hard to do the writing.
JAMES: It’s interesting to hear you say that because in one of my notes here that I worked out while reading the book was I really loved the perfect ratio of prose to code. It’s like you show me some code, and then you explain it. And so many books just go so wrong in one direction or the other. I was reading a book just the other day that’s just code, code, code. And I mean, they show you like a two-page script they wrote. Then they go through and there’ll be like a line of prose explaining what one particular method is which is then reprinted. I mean, I just got so beaten over the head by the code. And then, there’s other books where they just babble, babble, babble, babble, you know.
SANDI: Blah, blah, blah, blah, blah…
JAMES: …some code. But I thought, in your book in particular, the pacing between the prose and the code was just so perfect. It was like a conversation. It was really good.
DAVID: I want to jump in on that really quickly just because there are a few things I want to add to what James said. The first is that none of the code samples -- I read it on my Kindle. None of the code samples were more than a page and a half long on my Kindle. And that paid-off in two ways. One was I’m not flipping through, trying to keep a large application in my head. It was just a smooth application. The second thing is, all of your code examples were things that I could reasonably keep in my head while you’re explaining why they do or don’t work or what the trade-offs are between this approach and that approach. And that really, really is nice. I’ve read other books; I’m not going to pick on any. But I’ve read a few where you start reading and you get into that place where you’re going through like 10 or 12 lines of code. And it’s just like, “Okay, just give me a repository at this point.” But what we had there was just something that was bite size and it was really, really nice.
SANDI: First of all, let me say it is so nice to hear praise.
SANDI: Well, I won’t go overboard. Here’s the thing. It’s like…[crosstalk]. What’s that?
DAVID: Are we friends yet, Sandi? I could say more nice things.
SANDI: Yeah, we are friends. I love you all. I mean, I really live in a vacuum and I didn’t have as much feedback while I was writing it, which was a bad idea. I mean, it’s my own fault that that happened. And so, I had a vision of the reader in mind. And I tried very, very, very hard to communicate with that reader. I can't tell you. For all the people who might be listening to this who think they might write a book and then immediately put off by all this talk of pain. I mean, the thing that’s really great about it is feeling like that effort is paying off. And so, it makes everything worthwhile in the end to have it, to feel as if it is useful. Anyway, the hardest thing about writing anything is the examples. And I think everything that you guys are saying goes right back to that like picking good examples carries a book, right? If the examples are bad, you hate them. If the examples are engaging and [inaudible] and they teach you the right things, then they keep your attention. And so, I was lucky that my love of bicycles gave me a domain that interested me, that I thought might interest the readers. On top of that though, I thought there were two things that I did that I really, really cared about. One was that I wanted colors and text highlighting. And the other is I wanted it to be easy to read on eReaders. And those two things aren’t common really, especially in the big iron publishing world of Addison-Wesley. But I put a lot of effort into making sure the code would look good, like on your Kindle, and be readable on your Kindle and be in a chunk-size bite on your Kindle. It turns out that too were paying off. Lots of people want to read on those devices. So, it makes it reachable and you can carry your Nook or your Kindle around with you and read it. In terms of how the ratio of code versus prose, I feel like I just got that wrong over and over and over again. And then I’ve obsessively edited until -- like I wrote a lot of things that didn’t make sense even to me. [laughs] Like, I would write them. I would. I would write stuff. It’s like a classic thing where you try to explain stuff, like we’ve forgotten what it‘s like to be a novice. And I would write code examples and I would have the transitions between example A -- Example 1 and Example 2. And then, I would realize, I left like 14 steps out. And the part that the novice reader or even the intermediate reader needed to hear, I skipped it. I just like totally skipped it. I left everything out that would allow you, as someone who didn’t know these techniques, to go reproduce them yourself. And so, I think the size of the examples, the transitional steps. Like more and more transitional steps got introduced as the book went on because I was a miserable failure at taking the right size step between one example and the next. But really, struggling with the prose and trying to figure out how to explain all the intermediate steps drove the additional code transition examples.
JOSH: Sandi, one of the things that I find when I talk to a lot of software developers who write, is that we experience some parallelism between the process for writing software and the process for writing prose.
JOSH: So, when I wrote a book which nobody ever bought because they cancelled at the dock before it hit the shelves. But we took on the writing process as kind of a software development process with the same sort of cycle. Did you do anything like that where you have like test-driven development of your prose?
SANDI: I didn’t. I would say that I did a thing that’s probably similar. But for me, I thought of it as writing a story. Like a book is a story. It’s a story where there’s a bunch of story arcs and they curve around and they curve around and come back and curve around. It’s like spiral that keeps getting bigger with every chapter. So, I had that in mind. I just sort of had a beginning, and a middle, and an end. And every chapter has a beginning, and a middle, and an end. And I had a theory, I don’t know, like I wanted it. So, early on in the writing, I got some feedback from my editors that was a little too informal. [laughter]
SANDI: Yeah. And it probably was. I mean, I've formalized it up a little bit but still, I think it’s substantially less formal than most books like this.
JAMES: It is, absolutely.
SANDI: And so, I had to make a decision early on about whether I was going to like it’s in the -- whatever it is -- the Professional Ruby series. A lot of books in that series are pretty academic and formal. And so, for me, I had to decide whether I was going to try to find the voice, use my voice or whether I was going to try to be that voice, whatever that voice was that they wanted. And in the end, the writing was so hard that I was just, “Okay. I need to edit my language.” I was just like, “Oh, heck! I'm just going to say what I want to say. And I’m going to say it the way I want to say it. And if they hate it, well they can just not publish it.”
JAMES: So, let’s be clear. Sandi is not a professional despite the serious style. No, I'm just…
JAMES: I think you’re right and that really comes across. I have tons of examples written down from when I was reading it. Like for example, in that SRP example. You showed that off so awesome. And you just started off with this harmless little class, it’s fine. And you're like, “And then this request comes in and you do this.” And then I'm like, “Yup, I’d do that.” And then, “This request comes in and you do this.” And I'm like, “Yep, I’d do that.” And then I'm like, “Now, you’ve blown the SRP.” And it’s like, “Wait! Did we? Oh, yeah, we did.” It’s such a great conversation that just guides you through. Another one I've written down where you’ve mentioned something about using attr_reader methods for the variables and you have just been talking about public interface. And I'm like, “But wait! Those add to the public interface.” I had that question. And then at the very next paragraph, you’re like, “And of course, those add to the public interface, so…” It was really like a conversation. I can't stress that enough.
JOSH: So, we’re talking about the book now. I want to talk a little bit about just the flow of the book since we’re getting into that. And I got to say that there’s a lot of material in this book. So, if people are listening along at home or in your car, or mowing your lawn, whatever you do when you listen to us, hi! The flow of the book, I think is -- I mean, this is not just a book for people who know object-oriented programming and want to get better at their software development with it. It’s actually a really good teaching text for object-oriented programming because it’s so practical and hands-on with the things that really matter about object-oriented programming. And like James said, the conversational flow in it, I think, is really great. But the way that you talk through object-oriented design and then show the practical implications of, “Oh well, this is a public interface. Therefore, here’s how I have to deal with how I'm arranging the code that uses that.” Or, “Why would I want to talk to, in my own access or method, instead of talking instance variable directly. What does that do for me? And what’s the effect of encapsulation?” Polymorphism, let’s jangle with this. I love that everything was really concrete. That you talk about the obstruction and then you show concretely what that means for your code.
DAVID: The real power there for me was just that a lot of the concepts were things that we’ve talked about on the show, or I’ve talked to other people and they’ve explained to me. Some of them, I do on my own and some of them I don’t. But the thing that really got to me was just that by the time I was done, it’s exactly what Josh said. I had this, “Okay, this is exactly where I want to do this and why.” And you know, my codes going to be better for it simply because even though I understood the concept, I didn’t completely understand how to apply it. There was a lot of that in there that maybe really paid off for me.
SANDI: I mean, I feel like we suck at explaining things and that we had failed the people, especially the people who are coming up in Ruby. Like, what does it mean to do designs? But now, we can talk about big issues, right? Like, what does it mean to do design? What is all this stuff? And I know some of that stuff just because I came out of a SmallTalk world. I haven't read many of the books. I've read some of them. I've been writing code a long time and maintaining code a long time. And the stuff that’s in the air that helps me like somebody’s in the universal translator. Like I finally get it and then I can explain it. And what I find is I spend a lot of time drawing pictures in the whiteboards and telling people how to write object-oriented code. It’s really unfortunate to me that we have this sort of divide in our community between, there’s this academic world of stuff that we don’t really understand and we can't read the books and they don’t make any sense. There’s all these words that don’t really help us write code. And then there’s us, where we’re sitting everyday and we’re trying to produce products and get features out the door. And there’s this huge amount of knowledge that is incredibly helpful. It’s like we don’t have a good way to talk about it so that we can understand it and make use of it. My goal is really to -- like I didn’t really make up. I would say there are very few ideas in this book that I made up. And probably every idea that I thought I made up, I really just stole from somebody but I'm too ignorant to know that I did it. What it is, is a translation. It is. It’s like, here’s what these things mean and here’s why you care. Like here’s how to use them in your code. And it feels to me like there’s a lot to be learned. And we should learn it. Like, we can write better code in an easier way where we can produce the apps that make us happier. These guys, like Martin Fowler, Kent Beck, Bob Martin, there’s a whole gang of people that are part of this huge history - Ward Cunningham, that have information. If we could only understand everything they were saying, we could really improve our ability to rewrite apps.
JAMES: Sandi, you said at the introduction of the book that ‘Design is a finecast for a novice to work at’. And I thought that was a real testament to what you were just saying that this is for everybody.
JAMES: This isn’t for experts sitting around, having their philosophical debates. This is something we can all do.
SANDI: My definition of design is ‘how your code is arranged’. If you define design that way, then everybody who types a line of code is doing design.
DAVID: And if you're not thinking about it, then it’s probably just poor design?
SANDI: Well, yeah. Well, that’s an interesting segue into the debate in our community right now about design, right? Like some people would say they’re not thinking of design, then they shouldn’t think of design. What I would say is like, “Here’s what object-oriented design does.” It understands that for any problem, there’s an infinite number of -- well, not a number but there’s a bunch of different ways to arrange code to solve most problems. And if you understand design, if you understand all these things that the object-oriented design brings to the table, then you can predict the consequences of different code arrangements. So, you can say, “Oh, I could use Inheritance, and I would have this cost and this benefit.” Or, “I could use Composition and I would have this opposing cost and benefit.” And in this situation, given what I know about my app and what I want to do, I'm going to choose one or the other with some feeling that I get what the consequence is going to be. If you don’t know those things, you just write code and you have no idea -- you're making a choice about consequence but you don’t know what it is. So for me, understanding what I'm choosing when I choose how to make a code arrangements, it gives me more degrees of freedom about how to write apps that are going to be where I can push on them later. And they’ll change in the way I need them to.
DAVID: There are several ways of explaining because I'm teaching youngsters code. Youngsters.
DAVID: Intuition is what happens when you’ve forgotten seven ways to solve a problem. And so, you get faced with this problem and you’re like, “Ehhhh…” And what you mean by, “Ehhhh…” is, “I'm thinking about some trade-offs and they feel yucky.” And you haven't hit on one that’s perfect. And there isn’t one that’s perfect. They all have trade-offs. I love that.
JOSH: So, as Master Suzuki said, “In the beginner’s mind, there are many possibilities. In the expert’s, there are a few.”
JOSH: And both sides of that equation, there's a front and a back.
DAVID: Lest people figure out how accurately they are in thinking that I am arrogant, I feel like George Carlin. And I'm pointing this out because I'm going to toss the ball to Sandi here because you’ve mentioned this a couple of times. But one my goals for 2012 and especially for 2013, is to step back and say, “What can I do that’s new?” And what I love about POODR is that as I read through it, I kind of put people down. And I was like, “Holy crap! That blows my mind.” And George Carlin, he wrote ‘Napalm & Silly Putty’. At the preface, he said, “I've been doing this stuff for 20 years and I just barely think I've figured it out.” And your book has really made me realize that, “Ah, I feel like I just barely figured this out.” And then I read your book and I'm like, “Okay, got to keep working on it.” I mentioned that because in the pre-call, you said that you had the same experience which terrifies me because if you haven't figured it out, I'm screwed.
SANDI: Okay. Well, maybe you're screwed. I can't really speak to that.
SANDI: I think I'm like everyone, right? I believed that I knew something. And then, I started trying to explain it to other people. A couple of things happen when you write a book. It’s worse even in a blog post because like in a book, in this book, I felt an obligation to give, especially novices, explicit direction about how to behave. I feel like I had to tell them, “Go, do this. Do it this way.” I have to give them rules like early on the Dreyfus Scale. And so, that’s a horrifying thought like you want to paint a big target on your head. Like write a book and publish it and tell people how to write, how to design object-oriented code. Like, this is insane. So, I had that real tension the whole time. Well, I went ahead and this is what I wanted to do. I wanted to write a book where nobody could complain that I told people the wrong things. That’s what I wanted to do, right?
DAVID: A book with no trade-offs?
SANDI: A book that said this or that, or this or that, or this or that. A book where nobody -- it’s so personal. It was a personal fear thing, right? Like what I wanted to do was write a book that no one could complain about what I’d said on the Internet, where no one could take issue with me where I have to defend myself.
DAVID: How does it feel to have succeeded?
SANDI: [laughs] I wanted to write a book where I would never have the possibility of being wrong.
JAMES: That’s awesome.
SANDI: And so…
SANDI: Go ahead.
CHUCK: I want to address that a little bit because I highlighted a whole bunch of stuff that I drove the people on Twitter crazy because I was tweeting it when I highlighted it. You have a couple of quotes in here that basically outline, “Hey look, you know, there’s a risk here and there are trade-offs.” One of my favorite ones, I just want to read it here is that it says, “Practical design does not anticipate what will happen to your application. It merely accepts that something will and that in the present, you cannot know what. It doesn’t guess the future. It preserves your options for accommodating the future.” And so, what that says to me is you don’t always have enough information. You may never have enough information. You will never have less information than you have now. So make the design decisions that you feel like you have to and defer the rest, until you don’t have to anymore. And so it was basically, “Here are some rules. But use your best judgment because you're going to get more information that’s going to inform you better later.” And so, that kind of opens things up. Here are the rules but if you have the information that says that you have to break them, then break them.
SANDI: Yeah. And you can imagine, that was not the first thing I wrote.
SANDI: Because it’s true. It’s this tension. I felt the need to give people, who were not yet capable of making their own decisions, very clear guidance about how to behave. But I wanted to really avoid that. Like some people have this idea about design like design has a bad rep. There are people who curse and spit when they say ‘object-oriented design’. And I'm not one of those people, clearly. I really believe that design has a lot. Design will help us all but it’s a certain kind of design that’s designed to find a certain way. And so, what I wanted to tell people is -- the point I wanted to make really is there’s a bunch of trade-offs and there’s a point in your career when you get enough experience to make good decisions about the trade-offs like only you know. Only you know your app, only you know where the most likely points of change are. But for people who don’t have enough experience to make those decisions, we got to give them rules. And I have to give them rules they won’t hang themselves with, that they won’t cargo cult. And so, that challenge the tension between telling people, “Behave this way until you hate this rule.”
DAVID: I think you said that in the book.
SANDI: Yeah. As soon as you can make a cogent argument to me about why you should break the rule, you are welcome to break it. That’s how you know that you have enough experience where you can make your own decisions. But until then, until you can tell me why you shouldn’t have an [inaudible] reader for every variable, I won’t look at -- okay, here I'm going to have a little rant -- I don’t want to look at any code where you're saying ‘@something’ in your code, like don’t access that data item. Don’t treat it like data, send a message. So, I have a whole bunch of blanket prescriptions that I would give newbie’s. It’s like, “Always do this. Never do this.” Then, I'm keenly aware of it. I break all these rules myself. And I fully expect people to go out and break them too.
JAMES: Yeah. It’s clearly an excellent point.
JOSH: And if you cook, you got to follow the recipe until you get to the point where you know when you can make substitutions.
SANDI: There it is. Yes.
JOSH: Just try baking. [laughs]
SANDI: And here’s the thing. The way we get great new recipes is if someone breaks the rule. So, you make up new ones.
DAVID: I [audio distortion] because they’ve done something similar over and over and over and over again. And so, they know what the trade-offs are - going back to what we were talking about - they know what the trade-offs are of substituting this for that or adding this in, with everything else.
SANDI: Yeah. The recipes that are made up by novices, we never hear about them because they don’t win.
JOSH: I'm going to try and make this anecdote really short. I was just talking to someone about this recently. A mathematician was studying knots, in the field of topology. And his wife was an avid knitter. And he’s like, “Oh, I want to see if I can model knitting in Math and learn a new thing from it.” So, she shows him how knitting works and he writes down some mathematical descriptions of knitting. And he goes away for a few hours and plays around with it and he comes back and says, “Look! I've invented a new way of knitting. I just transformed some of these equations and I have a new form of knitting.” And he sits down and explains it to her. And she says, “Oh, we call that ‘purling’.”
JOSH: Which for anyone who knows knitting is purling is knitting from the other side of the cloth. And so, his level of sophistication was completely a different level from her level of experience practical knowledge. So, my point with this anecdote was that unless you have a good grounding in the accepted fundamentals of design and what all the pieces are, like, “Oh, I have a public interface.” “I have an Inheritance interface.” “I have all these pieces of it.” When you get to the point where you have to innovate, where you have to break the rules, you may not even know if you're breaking the rules or you're following a different rule.
SANDI: Yes. To me, the most powerful thing about that is giving something a name because once we know the name, once I know it’s ‘purling’, then we can have a conversation; and once we all agree about what purling is. And so, part of what I wanted to do and POODR was like take all those scary names and make them normal. Like, I don’t tell you what polymorphism is until after I show you. And I'm like, yeah, there’s a big long word for this but I don’t talk about Aggregation until after I show you, I don’t talk about Composition until -- because it’s like, we’re all doing it. Most programmers, even novices, are doing some form of most of these things but they don’t know the names and they don’t know enough about refactoring to do the transitions between them. [crosstalk]
DAVID: The really cool thing about that too was it’s kind of an experiment with the reader. You know what I mean? You know where you’re going but the reader is like, “What if we rearranged it this way?” Then like you said, you give it a name. But for us, it’s a discovery process. For you, it’s a guided tour, that’s what you’re giving us. But for us, it’s the process of, “What if we do it this way?” “Oh, I see!”
SANDI: It feels to me like there’s room and I don’t know what the media is for this. But that discovery process, there’s such a need for a way that people can go put their hands in an experimental space and like do the refactorings. I don’t quite…go, you go.
JOSH: So Sandi, one of the things that I kept wanting to see in this book -- so this book, like I said, it has a very conversational style which, I think, makes it very readable. And then, you have these summaries at the end of each chapter that says, “Oh, great! Here’s all the things I showed you.” But throughout all the chapters, there’s all these really practical prescriptive descriptions or prescriptions for how to do things really effectively. And I just want a cheat sheet for the book.
SANDI: It’s funny different people have come down on both sides of that issue and since of course, it was easier not to do it than to do it. I let that vote win. But yours is not the first voice, that should happen somewhere.
JOSH: And then what I want to see is I want to see you and Avdi sit down and prepare a screen -- let’s see. There’s nine chapters in the book. There’s eight chapters plus testing. I just want to see a screen cast series of just like showing this stuff in action.
SANDI: I am in agreement. First of all, anything that I got to work with Avdi on would be, ‘oh, so cool’. [laughs] So, that’s a win. But it confuses me a little bit that people do seem to want like talks, instead of reading the content, because to me, the reading is so much faster than the watching. But it’s clear that there’s someway in which our brains are arranged so that listening to someone talk and seeing them draw the pictures has powerful meaning.
AVDI: We talked a little bit about that at Ruby DCamp, right? I mean, we had that really well-attended session on drawing pictures about code. And a lot of people really got a lot from the different ways people have come up with for visualizing code or visualizing design. There’s a story I like to tell from when I was watching you present your talk GoGaRuCo where you -- I forget now the title of the section that you were going through but it’s like sort of a quick-fire section of going through, basically, transitions of a diagram. And I can't remember for the life of me now.
SANDI: It was a picture that I've done a Composition. I’d ripped out some…[crosstalk]
AVDI: Yeah. Demonstrating composition in a visual form. As you were going through, I actually heard somebody behind or next to me say, “Whoa!” It has these visual representations. They have a strong learning component for a lot of people. And they really stick with you and that’s one of the things that I kind of wish that I could do more in the Ruby Tapas videos is visual stuff like that. Number one, I don’t really have much of a gift for it. Number two, I generally don’t have time because I want such a quick schedule on those. I don’t usually have time to add a lot of extra stuff. But even there, I've noticed that it’s interesting in a visual medium how much sort of side band information you can sometimes add.
SANDI: Especially after that talk. So, Avdi and I were both at Ruby DCamp in the Spring. And we talked, we had this session he was referring to. We’ve attended this session on visualizations. And it really was fascinating to look at, to see the different ways in which people visualize codes. And I'm not only talking about like UML class diagrams here. I'm mostly talking about the transformations of one design to another. So, it would be a refactoring, say from an Inheritance to Composition or refactoring into Composition. It feels to me like there’s something powerful there. If we can figure out how to do images, moving pictures to teach people how to write a code, then it reaches a whole part of their brain that the words don’t reach. And I don’t know. I'm giving a talk at BaRuCo in Barcelona in the Fall. And it’s far enough away that I have time to think about maybe putting a whole talk together about visualization. So, I’ll do refactorings based on visualizations. Who knows how it’s going to turn out? I don’t really have any idea where I'm going with it. But for me, object-oriented programming is like I have this mental image of the app; the app in memory of the objects and the messages passing between them as it runs. And it feels like if we could draw that picture, that if you could do any animation of the message of your objects in memory coming and going and the messages passing between them, that you could play it like a movie. And you would be able to look at it and tell where the design was wrong.
JOSH: Have you considered doing flip books?
SANDI: I don’t know. I haven't. What I know is I don’t know how to do this. But what I do know is that if I had a chart of numbers and I made a graph out of it, I can look at the graph and know instantly what’s true. And I cannot parse the numbers. If we had a way to do that for applications, you would be able to see, “Oh, there’s too many message or too many objects.” Or, “There’s a bottleneck here.” Where it’s very hard to look at the source code on disk and tell that, which is what we do now. We look at the source code on disk and we build up these models on our brains about what’s true.
JAMES: I think you're really on to something there and just listening to you talk. That even in a book, you show an example and then you say, “And so, what you need to do is change that code to this.” And then you show another example. Even though we say we’re changing that code, that’s not what happens in the book, right? There’s that chunk of code and then there’s the other chunk of code. It’s kind of disk connecting our brain. And Avdi was a little down on Ruby Tapas earlier but one of my opinions is that it’s so powerful because I actually do sit there on video and watch him change that code from one thing into the other thing. And I actually wish Katrina was here right now because she would explain this much better than I would. But she talks about the shape of code, that we recognize a lot of things by shape. Like we see that and we know, “Oh, that’s wrong.” For some instinctual reason that we can see that shape, that bulky method, for example, and we know that that’s bad, right? And we have that instinctual reaction to the shape. So we were really watching Avdi in the Ruby Tapas videos mold the shape. It’s almost like he’s messing with Play-Doh and he’s reshaping the code while we watch. And I recognize that like you're saying is probably even better ways to show something like that than just a straight screen cast or something. But it is a very interesting topic.
SANDI: I'm waiting on someone to take it and run with it who can write the code. Like run your test, run the profile, or take that data and draw me this animation.
AVDI: I got a question that’s maybe changing the focus a little bit. I've already spent two hours interviewing you about your book. So, I don’t want to ask you anymore questions about the book.
JAMES: Drill her. Just make her sweat. [laughter]
AVDI: If anybody doesn’t know what I'm talking about, if you get the deluxe edition, the Sponsor Edition of ‘Objects on Rails’, that interview comes along with it.
JOSH: [crosstalk]…she’ll give you the right response.
AVDI: [laughs] What I’m curious about is sort of beyond POODR. Since we talked, you’ve been out and about quite a bit. You’ve talked to many, many people at conferences. You’ve done a little bit of, I think, going into companies and talking to them. What are the things that you feel like aren’t in the book that you’d like to talk to people about now, that people are asking you about and having trouble with?
SANDI: The interesting thing is that it will come as no surprise that people want me to give them advice about their Rails apps. They want to know how to deal with where you put logic if it doesn’t go in your FAT model. They want to know how to deal with presenters. So there’s that, right? What I find is that it’s like the book is fixed in the middle and there’s stuff on the left of it and on the right of it. On the right of it is like, how do you play these techniques to the Rails app and what are the best practices that the Rails community can offer you? And there’s a huge amount of dispute in the Rails community right now. Actually, there’s uncertainty and there’s dispute, we’ll divide those into two different categories. The before, maybe that’s on the right side of the book. On the left side of the book is it turns out that people need what I see when I go out -- like I'm at [inaudible], right? Some business invites me to go there. They want me to show up and look at their code. And when that happens, I walk into an office full of people and a bunch of people say -- the conversation goes like this, they say, “Well, we have this app. It’s a terrible mess. It’s got 100 classes in it, they're all [inaudible]. They’ll test run forever.” And, “I'm going to open up my test center and I'm going to point my finger at this method and ask you to tell me how to fix it. There’s this enormous amount of complexity that we build over a number of years and I want you to look at this bit of code and tell me how to improve it.” That’s what happens to me.
JAMES: And Sandi fixes it in 20 minutes and they lived happily ever after.
SANDI: You can imagine the terrifying thought that one is going to be in that situation. But what I've been finding is that all the problems are simple and that they're all the same. And also that the people in that situation want me to give them very specific definite rules about how to write code and I finally came and started giving it to them. I made up the rules for them. And so, it turns out that people have methods that are too big, they have classes that are too big, they pass too many parameters, they use ‘if’ statements and ‘case’ statements. And all of those problems really are symptom of one thing and the solution is the same solution - break it down into smaller bits. And so, what I've been finding out in the world is that the bits are too big and that people should make smaller bits. That solves huge amounts of problems. And if you know any of the object-oriented techniques about making things smaller, like do you know what bits you're looking for if you're looking for Composition, if you're looking for Inheritance? Then you just have a leg up because you can talk to your friends about it. So, one of the things I'm seeing is that on the right hand side, they want me to fix their Rails app, but on left hand side what everyone needs to do is go home and write smaller statements.
DAVID: You brought up Rails and I have to read this out of the book and then you can respond. I'm really curious to hear what you have to say. It says, and I quote, “Avoid writing frameworks that require users of your code to sub-class your objects in order to gain your behavior.”
SANDI: Yeah, don’t do that!
DAVID: How do you feel about Rails?
SANDI: I love Rails. And here’s why I love Rails. I can write a web app even if I don’t know much. I can write a web app if I don’t know OOP. That cracked the door open to let people produce products, to get features done, to make web apps. And we are in that business. We are in the business of producing features for our customers. And so, I have nothing bad to say about Rails. I use it, I like it, I'm grateful for the effort that people have put into it over the years. However, there -- and here’s…okay, it is the perfect solution for the problem it solves. Damn near, very nearly perfect for the problem it solves. However, many of us have a slightly different problem. And so now, we’re going to dive…[crosstalk]
JAMES: All of us have a slightly different problem because Rails is the Basecamp problem and there’s only one Basecamp.
SANDI: Exactly, yeah. I mean, like the CRUD problem. I would argue that if you have the problem of -- I have a database that I want to put a webinar face around and it’s straightforward. I have this direct mapping between a screen that the user sees and a table in a database and a row in a table in a database. It’s perfect for that. At that point, I'm going to have to get into some slightly more fuzzy language. Like if you think of the controller as the request is coming in from the users on one side of your app, and that’s on your left hand. And if you put your right hand out, you’d say, “The data where it goes on the database is on my right hand.” And if there’s a direct mapping between the data that’s going on your database and the request that’s coming in the controller, you can put your hands right together and that works. And it’s fine and that what Rails does. It wires them right together. However, if anytime that you have an impedance mismatch between those things, then you move your hands apart and there’s some space in the middle. And this goes to hexagonal architecture, right? If there’s a body of things that should fit between your hands and you put them in your left hand in the controller, or in your right hand in the persistence layer, what you’ve done is you’ve made it hard to reuse that logic which shouldn’t really be tied to either one of those things. And so, yeah, I think the Basecamp problem is the problem where the hands are pretty close together. And it’s really easy to write a Rails app to solve that problem. And it’s perfect for doing that. I believe that -- I would tell you that many, many people are in significant pain because of the Rails apps right now because those are the people who are talking to me. And they're in a pain that I believe object-oriented design can solve. And it’s not enough -- okay, let me back up again. Let me just say this. I have no interest in the fight - the design fight.
DAVID: Sandi, you are picking a lousy fight here. This is huge…
SANDI: I am not. When I take the Myers Briggs test, I'm a flat line right down the center, every time I take it. I mean, it is a true thing. Let’s just mention the elephant in the room, right? From David, DHH’s perspective, he is exactly right. And when I heard him on the Rogues, I agreed with 99.9% of what he said. For that problem, you don’t need to do much other than pour your logic into Rails. And you should do no more. It’s a waste of time and money to do more if that’s the problem you have. However, what I do object to, the only thing I really object to is I see a lot of people who have a different problem and it does not help them to say, “Don’t look at the design.” There are people who are in pain that design can help. And they should be allowed, they should not be dissuaded from learning the techniques that might improve their lives just because those techniques don’t necessarily apply to every Rails app. And the other thing I would argue is if you looked at Basecamp, I’ll bet you would say -- I’ll bet anybody who knew object-oriented design would look at Basecamp and say the code is well-designed. I’ll bet the design is good enough so that people would like it. Okay, I'm like a bad academic. And so, I can tell you that I once thought I made up the Law of Demeter. I did. I thought I made it up. I was having a rant to that and someone told me like the name of it. And I was like, “Really?”
JAMES: That’s awesome.
JOSH: Ignorance of the law is no excuse.
SANDI: I thought I made up the Null Object pattern. Actually, I did make it up. One day, I was working on something and I was like, “Oh, I just made an object that will just answer everything,” as if it’s okay.
AVDI: We call that ‘purling’.
SANDI: I believed that a lot of people who say, “Good design is a bad idea.” I mean, it’s not they're not good programmers. It’s just that they figured this stuff out themselves and they're already doing it.
SANDI: Right? And so why reinvent the wheel?
JAMES: [crosstalk] those particular pains.
SANDI: If it doesn’t hurt, just keep on doing it.
JOSH: So, Sandi…First off, Chuck, this is going to be a long episode, we’re not going to do picks soon. [laughter]
JOSH: Just get over it.
DAVID: I'm skipping my pick as well.
JOSH: So Sandi, the thing that people have used more than a couple of frameworks over the years. I think we’ve all had a similar experience that when you're building an application using a framework that the first -- I don’t know, call it a year or call it a month, I don’t know. But the first era, the framework is awesome and it helps you get stuff done and it gives you a huge leg up and you are out the gate right away and you got all this cool stuff going on. And it’s an incredible force multiplier for your productivity because the problems that you all have to solve at the beginning of your application are pretty similar kinds of problems. And then when you get into the middle of your application or the second era, then the framework is sort of ambivalent. It’s still got the structure and it’s influencing the shape of your application but it’s not really providing as much leverage for productivity as it was in the first era. And then in the third era, the framework is actually interfering with you being productive and creating new value in your application. And then many applications, there’s this fourth era where they’ve sort of built another framework on top of the framework to help them move forward. Does that sound accurate to you?
SANDI: In shorter terms, yes.
SANDI: Rails One, Rails ran in 2006 and it’s 2013. I've been alive long enough so that my -- I have databases that are now on their third different framework wrapping around. They had SmallTalk over them, they had some Java over them. Now, I have Ruby over them. Now, I'm looking at -- I'm wondering about Go, I'm wondering about functional languages. I'm wondering about other things I can do in Ruby. It’s like the framework. And so, in order for my data to live into the next generation of technology, what I want to do is have most of business logic not be wrapped up in a framework. And I think in some ways, that parallels with what you just said Josh where at first, like all I needed to do was put up a web app. But then as the business logic became a bigger and bigger part of that app, it was important for me to preserve my investment in that business logic by having it be independent of framework. Like I said, I love Rails. I've used it used everyday. Well, not really everyday but I use it a lot that I don’t want to be stuck like Rails isn’t the only framework out there. If you look ahead in 20 years, are we all going to be doing Rails?
JOSH: Oh, I hope not! I'm going to be retired.
CHUCK: Rails version 50.
SANDI: Yeah. And in some ways, we’re living in a world where the Rails community is not -- like when the Rails community was startups that came and went as the VC capital ran out, then you're…those are not my peeps. My peeps are the people who write big apps or even small apps where the data is what has value. What we’re trying to do is put a face on that data so users can interact with it. And so in that sense, the frameworks come and go and my goal is to have the framework give me the most value for the least trouble. And it’s important to me that frameworks, that I’d be able to write code that I can keep even when the framework is gone. That’s not a perspective that you have on day one of your first job at a startup.
JAMES: That’s a really great answer. And you probably don’t know this but you're playing heavily into this kind of perma-debate that we have going on, on the Parley mailing list where the DHH is explaining a lot of his ideas to us and some other people, Corey Haines, Josh, Avdi, myself in particular, are providing some counter points.
CHUCK: That was a great way of saying we’re all fighting with DHH.
JAMES: I can't tell if we’re winning.
AVDI: I don’t think we’re completely fighting.
JAMES: No, we’re not. It’s actually a really excellent conversation…
CHUCK: It is.
JAMES: …where DHH is making a lot of fantastic points. And while some of us believe he’s wrong on some of those, it’s very well-done and it’s a great discussion. I would love to bring all of it here but I can't. Let’s do this one part because it ties into a lot of what Sandi says. In that thread, we’ve had a lot of talking about things like object-oriented design, things like dependency injection, or hiding your instance variables behind methods or things like that versus the counterpoint of YAGNI. So, doing this upfront and I come down on the side where I don’t take YAGNI to be straight in the center. It could be this or it could be this. So, I’ll pick the perfect halfway point and do that. That’s not what I do. I go, “It could be this or it could be this. So, err just a little bit on the side of design.” For example, I've usually injected dependency pretty much just right when I put it in. And my reasoning for that is that I found it makes the code more flexible in the future and thus, those objects tend to get used more. Whereas if I don’t do that, then what I find is that I don’t use those objects more because they're not as flexible, right? So, it basically becomes self-fulfilling prophecy. Anyway, I showed something like that to DHH in the thread and my example was probably pretty bad. But he tore it down as classic YAGNI, “You’ve added a few lines for a problem you don’t have now,” et cetera. I was wondering Sandi, where do you fall on the divide? Do you literally not start introducing some design until you felt a bit of pain there or do err a little bit on that side? It would be good to hear your thoughts on that.
SANDI: For simple coding techniques, there are some that I pretty much follow all the time. I break these now and then, but my pattern, like there’s some things where I think -- there are some decisions where the cost is the same whether you do it way A or way B. For that, I'm going to say instance variables. Like to me, the cost is [inaudible] and sending the message to get that object versus the cost of referring to the object itself by referring to the variable. Those are so close to being a wash that I never refer the instance variable, that I always send the method. And so, lots of these decisions that people say, “YAGNI,” I’ll be like, “It doesn’t matter.” If it doesn’t matter in the present, I’d do the thing that leaves me the most moving room later, the most flexibility later. Along those lines, so one is instance variables. The dependency injection example is an interesting one because when I'm forced to give people a rule, what I tell them is never refer to the name of a class inside another class. That rule means that you always have to inject every dependency. Now, I’ll tell you that I break that rule. I break it. But mostly, I inject dependencies rather than getting a new instance of a class in another class. And I can defend this as saving me money today. And I’ll do it. I can do that by saying, “You always have two uses of a class. You have the rest of your apps makes of it and the use that your tests make of it.” And I get so many benefits by being able to inject dependencies in my tests so that I can stick some other object in there if I need to [inaudible] and make a test double, that I feel like -- the good analogy is buying lottery tickets, like I'm buying a lottery ticket every time I injected dependency. And they don’t all pay off. But if I do it all the time, it goes back to what you were just saying, James. There’s enough of the time that I discover that I save enough money in testing or I discover that I do reuse it or want to inject another kind of object. That pays off often enough so that I feel like I save money today by generally thinking about code in terms of injecting its dependencies. The whole YAGNI thing, like I'm a true believer in YAGNI and I almost never cause myself a problem with under design. Like when I make a mess, it’s very often because I have picked an abstraction too soon. And so, I've gotten way more comfortable with leaving messes in my code where I expect to find an abstraction and do a refactoring. But I'm going to wait on like three cases instead of two. I’ll put a case statement in there that will have two branches in it because I think I'm going to have a third and I normally get rid of it but I'm waiting on more information. For me, the decision point about whether to reach early for the abstraction or whether to leave the mess and wait to fix it later, it depends on who’s going to make it.
JOSH: That’s a great sort of high level conversation about that. And I’d like to, if I can, drive that down to one particular issue as an example.
JOSH: In Chapter 6, you're talking about Inheritance and what are some good ways for designing that essential Inheritance interface. I remember many years ago, first encountering the concept of an Inheritance interface and that if you're building a super class that you know people will be making sub-classes of, you have to design it with that extensibility in mind. I loved what you showed in the chapter there. I got to the end of Chapter 6 and I looked at what you had created for the super class, sub-class decomposition there and how you factored that out. When I looked at the code at the end of Chapter 6, what you had in the sub-class was something that didn’t need to be a sub-class at all. And that there were no calls to super in it, there were no dependencies on the internal structure of the super class. And I looked at it and I said, “This is Composition. This doesn’t need to be a super class/sub-class relationship at all.” And then a chapter or two later, you showed, “Now, we can refactor this code into something that actually is Composition.” And the thing that I saw at the end of Chapter 6 was, “This is actually a really good set of diagrams for people who are building Inheritance APIs.” That’s great. But my look at it was maybe it was just like refactoring too far. It had gone to the point where, “Okay, we have our class units now just about ready to be turned into a Composition relationship rather than an Inheritance.” And I think that when I'm building things in mind, I'm going with the Inheritance as a way of extending things and composing things in my code that I'm okay with tighter coupling. That’s sort of what it’s about.
SANDI: I don’t at all disagree with you. If I maintain the code, I can leave all kinds of messes and wait in on more information because I know I trust myself to fix them. One of the things that I confessed to Avdi when he and I talked about the book was how bad I am at making class method. How much I err in making class methods. I make class methods all the time and I know they’re wrong. But in the present, I can never figure out, “How is this going to hurt me? This seems like the easiest, cheapest way to do it right now.” And I’ve gotten to the point where I’ll just do it. And I’ll know that eventually, I’ll figure out why I hate myself for doing it and I’ll fix it then.
SANDI: Yeah, and it’s the same way with Inheritance. Since I came from a world where I didn’t have modules, I have Mixins. So, Inheritance was often our only choice. It was a choice, it wasn’t the only choice. Obviously, we could have used Composition. But we use a lot of Inheritance and SmallTalk. And I think the refactoring of that example in the book all the way to the point where you can easily change it to Composition, I have that bias because I have used Inheritance too much and had to push it all the way to there to get out of it. And so, if you maintain your own code or seeing your people maintaining your code, your obligations about what to leave change and leaving things so that the people who come behind you can do the right thing. Like that’s the last question I ask about code. When I write it, I do the right red-green-refactor. I work on it, I get to where I'm going to check in and I run a diff. And I look at all the methods. I added all the names of it and all the parts. And I think, “What would this look like?” I run the test and I read what the test say, what the story it tells. And I say, ‘What does this look like,” to someone who knows nothing about the code. And I have that bias because I write a lot of code that other people maintain. And so, the last thing I’d do is go fix the names and fix the ‘if’ statements in the test and break the methods up to make them a little more intention revealing. But if it’s my code, I'm just like, “Ahhh, I’ll deal with that later.” We can use design, like I'm a designer and you would take my badge away. You would take my card away if you could see some of the code I write. And that’s okay, because we’re just trying to save money. We’re trying to get code out the door. But the point behind learning these techniques is not to use them all the time but to understand how to use them when you need to and how to get to them once you have a mess. Because most of the code we write involves -- most of the design problems we have are problems of refactoring, not initial problems. It’s rare that we do, we’re not doing perfect design for the whole app on day one. We don’t know enough. What we do is we write a bunch of code, we throw it out the door and then we get more information and we have to get from here to there. The problem is getting from here to there, right? You wrote some code you threw it out the door. It’s good enough, and then change happens and you have to decide how to do it. So now, I need two things, I need to understand what change I want to make in the code and I need to have enough refactoring skills to get from here to there. So those two things, like deciding where to stop really depends on who’s going to maintain the code.
CHUCK: So, I have another question. I'm going to completely change the topic but while I was reading the book, I read through probably the first eight chapters and I was like, “Okay. I really like these approaches. I've really learned a lot about these. But there was something I wasn’t quite comfortable with about.” And what it turned out to be was all the stuff in Chapter 9 which was, “Okay, well I’ve designed all these interfaces to accept these messages in these ways but I didn’t have a great way of proving that they did what they were supposed to do.” And so, Chapter 9 which is honestly, the longest chapter in the book, but for me, it was the biggest “Aha!” And it was just one thing after another because it was, “Here’s how you approach this to basically make your test as flexible as your code so that it can actually prove that your code does what it’s supposed to do without repeating itself and without being too robust.” I really, really appreciated that just for the sense that it made me comfortable in implementing the rest of the stuff that you put into the book.
SANDI: Isn’t testing cool?
JAMES: Heck, yeah!
SANDI: I mean, it is, yes. So, I don’t think I had anything to write about testing and then I sat down and tried to figure out what I would tell people to test. And then I realized, “Oh!” There’s like three simple rules, right? Test, make assertions about state for incoming messages and make assertions that you send to outgoing messages and ignore private methods. Rules are really simple. But it turns out they're incredibly powerful. And also, test roles. Make test approvable to play their role. And there’s four things together to make everything easy.
CHUCK: Can I push back on something really quick on that and that is that a lot of times, I’ll compose methods out of private methods. And most of the time, you're right that you test your public method, you test what comes in and goes out. And that’s fine. But sometimes, I kind of codified a complex sequence of things I have to happen into a method on a class. And a lot of that winds up in private methods just so that I can say, “Look, this is the interface you want to use. And the rest of the stuff just makes it so that I can read what I put into my public method.” I can't get to those private methods directly. And so, it usually turns into a battery of a whole bunch of tests to manage the complex process that’s there. Is that an indication that I have a problem?
CHUCK: Or is that something that I may have to reach in and test my privates?
JAMES: Nope. It is a common problem actually. And I have a pick for this episode that’s exactly about that. So, how about we save it for there?
SANDI: So does that mean I shouldn’t express anything?
JAMES: You can but…[crosstalk]
CHUCK: Express please.
SANDI: Here’s what I would say. Don’t test private methods unless you really need to. In which case, test them as much as you want. I have code, and this is what happens, right?
DAVID: I love you, Sandi. I love you so much!
SANDI: Here’s the deal. So, you have private methods and there are nasty gnarly complicated unstable things. And if you just test the edges, if you just follow the rules I gave you and test the boundaries of your interface, if you screw up a private method then it’s really hard to fix it because the error message is a long way from the thing that failed. So, the writing test of private method means that you're writing a test that tightly couples you to something that’s unstable. And there’s a cost and a benefit to that. If you break it, if it ought to work and you break it accidentally, your test will tell you -- they will drive you very close to where the problem is and make it easy to fix. However, if you decide on a different -- if you decide to change that unstable private implementation to something else, then you have to throw your test away and write a new one. It may be that it’s worth it to you to test a private method because -- when I'm writing a new class, I often have tests for all the private methods in it. And then as things settle down and I feel like the private implementation maybe is more steady, at that point, either I take the test of the private method out or I put a little note in there that says, “If these break, delete them.”
DAVID: You uttered a heresy that just lit me up so happily. You did a Lunch n’ Learn at Heroku and you talked about testing. And you talked about testing private methods and you got through the, “If it’s hard, go ahead and test this so that you can work your way through it.” And then you said something that made my jaw hit my chest. You said, “And then once it’s working, delete the test.”
SANDI: Yeah. You don’t need it. It’s just in your way.
DAVID: It’s in the way of anybody who comes after.
JAMES: One of the ‘Destroy All Software’ episodes recently was really good about that. He gets a bug report and it’s something like, “When I go to this link, I’d get an exception.” And he said, “Alright. Let’s debug this using test.” And so, he actually starts from a high level driving the application kind of test and he figures out what the scenario is to hit that URL and get it to throw this exception. So then, using nothing but the stat trace, he goes down one level further and basically tries to write that test and just the controller-level test, directly hitting the action, triggers it again. Then again, using nothing but the stat trace, he goes down to the model layer and figures out what it is there. It is really cool bit of programming. He’s not opening the code. He’s not looking for that bug. He’s just writing this test. So what he ends up with is like this layer cake of tests that led him to the bug. And then when he fixes it, obviously he verifies that the whole layer cake works. But then, he also talks about how, “And now, we can probably remove a bunch of these tests because they were just for me.”
CHUCK: Or leave them in if they add value because you did have coverage around that one way or the other.
JAMES: But the problem is he covered it in three different layers. Let’s talk about how there might be some value to leaving them if it’s like a user interfacing feature that is costing you money when it breaks or something like that. But in most cases, what he basically did is he reduced redundancy in the test that didn’t really make sense, right? He could at least cut off two of the layers and leave the other one.
CHUCK: Yeah, only one layer has real value.
JOSH: The one thing that I got to say about -- actually, I have two things to say about Chapter 9. One, Chapter 9 was awesome. I loved the, “Here’s the different ways that you test this stuff.” And I'm pretty sure that I've done all of those things multiple times in applications, but never quite that methodically. I think Chapter 9 is going to be completely dog-eared as I work on my next app. But the thing about it is that I agree that this is the right way to write a large body of tests and this is going to give you much more maintainable tests as you get a big test sweep. The thing that I have a little bit of reservation about is like you said, “Design is hard.” And while this is like the right way to do things that just like program code can have bugs, test code can have bugs and can have design errors. The thing that feels like is missing is the safety net. When I do Rails applications, I’ll do acceptance and integration tests so that I have a happy path through my application just to make sure that everything’s stitched together the right way. And the testing approach that you talked about in Chapter 9, I think it works and I tried to poke at it even though it was sort of late at night when I was reading. I tried to find holes in the testing approach but it really does seem like you have all the pieces hooked together. What it doesn’t have is like some allowance for people who are going to get this wrong sometimes and what’s the safety net that they should be doing to make sure that they don’t screw up their test in a way that screws up everything else?
SANDI: It’s completely missing innovation test. That’s what’s missing, right? In the end testing. What that chapter is, is about unit testing. And I probably don’t ever say that anywhere in the book. It’s the cause of the example app. Like, this is an app that fundamentally has no user interface. So, it’s hard to know where the edge is to test it. There are very few use cases that go all the way through. So, the short answer is I totally agree. Like this is not enough. But I tend to write unit tests and integration tests and nothing else, nothing in between. And it makes me put all my code in something that’s unit testable which is a good thing. I can't have helpers. I can't have code views. If I wanted to be tested, it has to be in a PORO, in some kind of object that I can get to any unit test.
CHUCK: A PORO?
SANDI: Plain Old Ruby Object.
SANDI: Yeah. If you make that rule that says -- if you're afraid to write code without test which I am having, once you write your first test and you realize how bad your code is, then you're ruined forever. I definitely want to write tests and I want to write tests first code but I don’t want to write controller tests. And so, I end up in Rails apps. That drives me toward trying to put everything in an object that’s easily testable. And so when I do that, then I just have the bottom level test like in Chapter 9 and then there’ll be some wrapper test at the edges of the whole application and that’s where the safety net is.
JOSH: Okay, good. Maybe when you revise the book.
SANDI: Shoot me now.
JAMES: I was actually thinking earlier, I can't remember who asked Sandi, what would they like to include that they didn’t. It was Avdi. What I wanted and I actually took a note about this when I got to the end. What I wanted was a lot of your examples. You know, we’ve talked about the conversational styles and it’s this class moves into this other class or maybe two classes if you’re splitting something out kind of thing. What I want for a second edition or a follow up or whatever is some cases where we move up to the medium levels of complexity of object interactions, where you’ve got like a handful of objects interacting, and you're applying these rules to them.
SANDI: And it feels like the book is a terrible medium for that. Like it does need something like we were talking about before where there’s some other, some websites on interactive thing, where people can go and get up to their elbows in that sink of objects in a way that you can easily manipulate them. I don’t know really what that is but I am deeply sympathetic for the fact that it’s the next step for learning.
CHUCK: I have a question, Sandi. You mentioned you test units and then you test innovation. One -- I won’t say anti-pattern. I will say one effect, when I try to do that, one result of the trade-off that I end up at is that I end up with these objects that are well-tested but the interactions between them are not tested to my satisfaction anyway. Is that because -- are you creating more objects that encapsulate those interactions?
CHUCK: Thank you. Open my fridge and turn on the light. Okay.
SANDI: I've been wanting to give -- okay, so people wanted rules for me like when I go out and see strangers when I look at their code. So, I finally gave them some rules and the rules are, and this is painting a big target on me to give you these rules. But I want to say them to you and see what you guys think about them.
SANDI: Okay. So, I ended up giving, “This is the bottom line. Your class can be no longer than 100 lines of code. Your methods can be no longer than five lines of code.” I wanted four but I felt like I had to give them five. “You can pass no more than four parameters and you can’t just make it one big hash. Your controller, in a Rails app, when a call comes into your controller, you can only instantiate one object to do whatever it is that needs to be done.”
JAMES: I love it!
SANDI: “And that your view can only know about one instance variable.” So those are the rules I gave them. I told them they could break them, right? They could break them.
CHUCK: But then everything would be too simple.
SANDI: Yeah. So, what do you guys think about those rules?
CHUCK: I feel terrified.
JOSH: Who’s the audience for those rules?
JAMES: You Josh, you.
SANDI: This was a shop of people who had mid level experience but had created some big -- they had a control with many, many lines of code in it with many, many modules and views that had so many instance variables that they felt like they just had to set every instance variable known to human kind to make them work, right? I mean, these are people -- I would say, everybody. Everybody is the audience for that rule, frankly. Like, if you don’t know the rule -- if you’re afraid of making a mess out of your Rails app and you follow these rules, if you could figure out how to follow these rules, I think you would stay out of trouble.
CHUCK: So, one thing that really strikes me with these rules is that for the most part, if you really try, you should be able to follow them. And if you can’t follow them -- see, this is the thing with programming rules that I think people don’t understand is that when you say, “I’m giving you this rule,” they think, “Oh well, I’m sure I can find an instance that breaks this rule.” The whole point is yeah, but when you break the rule, you should be able to explain exactly why you need to break the rule. In that way, then you can justify what you’re doing. But otherwise, you’re not forced to think about what you're coding and that’s really what the issue is.
AVDI: That’s a fantastic point.
JAMES: I agree.
SANDI: I told them they could break the rules if they could talk their pair into agreeing with them.
AVDI: Yes, and that’s good.
JAMES: That’s awesome. [crosstalk]
AVDI: That is why I like the term. I’ve seen a lot of pushback against rules. Let’s call them guidelines and stuff like that. [crosstalk]
AVDI: I mean, as far as words mean anything, that’s why I like the term ‘rules’ because it has that implication that you need to talk somebody into -- you need to explain to someone why it’s okay to break. That’s exactly right. If you can explain to your pair, “This is why it makes sense to break this rule here.” And they agree with you. [crosstalk]
CHUCK: Or to yourself.
CHUCK: But the thing is if you’re doing it by yourself, because it’s hard is not a valid reason for breaking that rule.
JOSH: So here’s the thing. And it goes all the way back to the title of the book, Practical Object-Oriented Design. And the thing that I think is the hidden magic in this book, is that every chapter when Sandi is talking about the trade-offs that are involved in these things. One, she’s upfront about the fact that it’s all trade offs, and that it’s all about ‘what is the cost of doing the work’ and ‘what is the benefit that you get out the other side’. And these rules, Sandi, these rules that you’ve talked about, I think they're great as goals and yes, you should be able to break them when you need to. But the thing is they’re sort of tuned for ‘if I do the work to follow this rule’, most of the time, I’m going to get a benefit from it down the road. And that when you’re evaluating breaking the rule, I think the right mindset for that is ‘how much is it going to cost me to follow the rule’ versus ‘how much…’
SANDI: It’s going to save me, yeah. It’s about the money.
CHUCK: And when we’re talking about breaking the rules versus not breaking the rules, we’re going back to the conversation about whether or not we have enough information. That information doesn’t have to come from the user, it doesn’t have to come from the product owner, sometimes it comes from, “Gee, I’m going to break this rule and see what happens.” And when it comes around and kicks you in the rear end, you go, “Oh, I now have enough information to know that this design decision was the wrong one, and I’m going to go the other way.”
SANDI: Yeah. And very often it means breaking it into small bits, which is what all these rules make you do. Like if you have to break things into small bits, you're going to really try for the bits to have high cohesion, right? And so, lots of things naturally fall out of this, it’s like whatever. These are arbitrary guidelines that I gave people who were really desperate for help about how to make decisions in the present where they felt like they didn’t have enough information. But the decisions that they’ve made in the past, using the same criteria had turned out very badly. They don’t know enough to do the right thing and they understand that there is a better thing. And they can explain these patterns, some of them, but they don’t know what to do right now. They haven’t bridged that gap yet that will keep them out of trouble in the code they write today. And so, I don’t know. It was my best guess about how to give them some sort of practical guidance.
JOSH: To people in that situation, anything is better than nothing.
SANDI: It felt like it. And they were -- who knows how it will work out? I’ll check back in and find out like, “Are you following the rules, first of all? And if you are, did they seem more helpful than harmful?” I mean, I know that my code looks a lot like that. I mean, what would you guys say? Does your code -- if you evaluated all the code, the most recent Rails app that you wrote based on those rules, would it mostly follow it or would it mostly not follow it?
DAVID: So, Chuck, our client listens to the podcast.
CHUCK: I know. [laughs]
DAVID: I'm going to go ahead and take the bullet for both of us and say, “Hell, no!” And my experience from this, I get this simultaneous thought that has been recurring to me frequently. I didn’t link them together until just now which is that programmers, I have observed recently especially, have an incredible ability to tolerate pain and just assume that it’s unavoidable. So, why try? And I listen to these rules and I'm like, “We break all of these rules and we know that at some point, we’ve broken the rule.” Sometime around 750 lines of code in the class, you start thinking, “Maybe this class was too big.”
DAVID: Maybe. And what I'm realizing is that I break all of these rules regularly. I personally at some point, I have rules -- well, I don’t have a hard and fast rule. At some point, I know it’s too big but I sneak past your rules without sensing any pain and I…
SANDI: So, let me ask you a question then. Why is it that -- I think we, as human beings, have a bias. The bias is to let it go too big more so informally than to break it up too soon. It’s kind of like, if I’m going somewhere in my car and I could drive past a bunch of intersections, I usually make the last possible turn to get to the place I’m going. I don’t turn at the first opportunity. I turn at the last chance. And so, it feels like we are biased toward letting the thing, to continuing to do the thing that we’re doing. And when I ask people, “Why don’t you have a lot of little classes?” They very often have an answer to that question. They say, “Oh, it would be too many small things and it would be confusing.”
JOSH: DHH said that in one of his Emails. He said, “I don’t want this proliferation of classes.” Like having too many classes in your file system would be a problem.
DAVID: I will own that because I have actually said that. That’s what I hated about Java programmers. Too many classes and I couldn’t keep them straight.
JAMES: Let me give another good example of that. I was actually having a conversation with a slightly more junior programmer recently and he had a class where it was very clearly doing two things. Like on one thing, he set up this scenario and then on the other thing, he handled that scenario. And I told him, “You want two classes there. One that sets everything up and one that handles the thing.” And he said, “But if I break them apart, I can’t see them together and they’re related.” And I said, “That’s a problem your editor solves with something like split panes or something like that. That’s not an issue of the code itself.”
CHUCK: It’s funny to me that you guys are bringing up these reasons to keep it together. Usually in my case, what the deal is, is just that somebody asked for another feature, it was really easy to just glom onto the class that I already had. I might have to tweak one or two methods but it’s not a big deal. So there is no pain to add it. The pain comes in later when I have to modify something that’s already there in a major way. So, I don’t feel the pain until I have to split it up. It’s in attention.
AVDI: I feel like there’s a common perception that adding a class is a heavy weight operation. [crosstalk]
JAMES: That’s right.
AVDI: I’ve even felt this myself sometimes. And I’m not even really sure where it comes from because, I mean, it’s not as heavy weight as it is in a lot of languages but it’s there. And there are some things that maybe Ruby could even do better like the fact that if it makes sense to add a class but you’re really just going to be instantiating one object in one place, it would be nice if Ruby made it easier to say, “I just want basically a singleton here, a one-off object that has these traits and that’s it.” You can do that but it’s syntactically harder than it ought to be. I don’t know what all can be done to lower that perception of it being heavy weight. Maybe we all need a sprout class macro in our editors. One thing that you can do is, you can do more internal classes. So, if part of that it feels heavy weight is the fact that you add a new file every time you add a new class, consider if you’re just sprouting a new class, maybe just sprout it inline for now inside the class that you’re working on and then factor it out.
JAMES: Great idea.
JOSH: I just want to say, that can be a little dangerous if you’re working in Rails and the way the class loading works.
AVDI: Yes. There are a lot of little ways that the Rails conventions kind of makes these things a little harder than they ought to be.
DAVID: So if I can articulate my personal pain, do you guys want to take it up? I know we’re way over time. But I’m getting free consulting out of Sandi, so I just can’t pass this up. [laughter]
JAMES: Sandi, we’ve got a few apps you're going to need you to look at after the podcast.
DAVID: Exactly. So creating a new class is not hard. Potty training a new class frequently, for me is. What I mean by that is I feel like if I split an object into two separate objects, now they both have independent life cycles and I feel like that -- I learned object oriented in C++ which is kind of like learning to program in basic, it’s just an extension of brain damage and I accept that.
SANDI: I hate that for you.
DAVID: Yes, me too. So when I create this object, I don’t want to have this object that’s partially constructible that might be in an inconsistent state. I feel like I suddenly have to worry about set up, tear down, life cycle, protection, capsulation. Am I worrying about the very feature I should be embracing?
JAMES: Yes, can I take a stab at that?
SANDI: Yes, please do.
JAMES: Yes, because to give an example, just that I ran into the other day. I had some class that was doing interaction with some response from an API. And one of the things I was doing there is parsing the ‘J’ sign it gave me. So when I wanted to parse that ‘J’ sign, of course, ‘trap errors’ in case it gave me crap or whatever, a few things. So there was a few parts to that parsing. And originally, I did it inline and then eventually, I'm like, “Oh yeah, that belongs in some class.” So I split it off and then I would just create this instance with the data and then call this parse method or whatever and it will give me the real Ruby back without any errors or whatever. So I split that off and I thought, “Okay, good. That’s separate now.” But then, what happened is I realized I was doing that all over the place. I mean, who doesn’t change some ‘J’ sign into something. I don’t want errors. I just want the result or whatever. And so, that little class that I split off, you talked about, “Oh, but now it’s its own thing.” Yeah, that’s what’s great. Now, it’s its own thing. And I went back and ripped out about ten places in my app where I was doing that and just made that class and used it.
DAVID: Isn’t that awesome that you just pile everything onto it?
JOSH: So this is where I get to crow about my achievement on locked from last week.
JOSH: James, so in the DHH episodes throughout on Parley and I know we’re not doing Best of Parley anymore but because we have over 500 people on Parley now.
DAVID: You just broke some people’s hearts right there, Josh.
JOSH: Yeah. So in that thread, David was -- we were talking about various patterns and how to basically decompose things into manageable chunks. And I tossed out a pattern that I've used where you basically make up. People have been calling these things Form Objects, but I think of them as resources. They’re not active record models, but they’re still models and that there’s something that you can put behind a restful controller. And it’s a very frictionless way to structure parts of your application so that they use the Rails conventions effectively. You can get a lot of leverage out of just throwing an object behind a controller using mapped out resources in the routes and, bam! You’re done. And it’s very little code to pull out something from one model and make it essentially a first class resource on its own. And the process of pulling that out, I find that the mechanical steps of actually doing the work, to pull that bit out and put it in its own class to manage those interactions, is far less work than fretting over, “Should I do this or not?”
SANDI: Just make the object. Just do it!
JOSH: When I get to the point where I’m suffering with it, it’s like I’ll spend like three or four hours wondering, “Oh, how can I do this within this thing?” And then I just bite the bullet and say, “I'm going to pull it out in its own thing.” And ten minutes later, everything’s better.
JAMES: Kent Beck talks a lot about this, right? That once you're giving yourself that other object, now you have that logical place where that stuff goes. And then you realize, “Oh, yeah, this would make more sense here, and then this thing can handle that.” It’s funny how it frees your mind because it separates those concerns for you.
JOSH: Corey Haines calls that a behavior attractor. But anyway, the achievement unlocked was I showed this example and DHH looked at it and said, “That’s a great looking pattern.” [laughter]
JAMES: Which is almost the exact opposite of what DHH said to me. [laughter]
JOSH: If he likes it, it must be good, right?
SANDI: So, I want to respond to like the last three things that got said, and I wrote them down.
JOSH: Go for it. Go for it!
SANDI: Don’t mind me. I’m just trying to get a word in edgewise with the Rogues.
CHUCK: It’s hard. Trust us, we know.
SANDI: But you know, I’m just teasing you because I know that I’ve spent the last two hours talking. So we were talking about too many small versus a few big, right? That’s the design tension and Chuck, I think, said, “That’s not really what happens to me. What happens to me is that I have a little bit of new behavior and I put it in an existing object. I put it in a place most like where it ought to go.” Then David was like, “I don’t really want to make more objects because I feel like I have all this set up, I have this tear down like they bring.” It feels like they bring these burdens with them to have new objects. Does that characterize what everybody said correctly?
DAVID: Yes, pretty much.
SANDI: So my response to David would be, your objects are still too big if they feel like they need a lot of set up tear down, right? They’re still too big.
SANDI: So, what happens is if you’re already in the situation or if you’ve already fallen off the cliff and you have this 750 line object, and you divide it in half, those objects are still too big. And very often, people have a hard time doing these refactorings because they cannot see that their life is improved by that first change.
JOSH: It’s like finding a guy who’s driving an RV around and complaining about how he can never get down narrow streets or find a parking space? And you tell him, “You should really be riding a bicycle.” And then he goes out and gets a giant three-wheel bicycle, with one of those trailers that you hook up to, to carry everything around on. Like doesn’t get the whole idea of bicycling, tries to get a bicycle that’s as much like an RV as possible.
DAVID: I think you’re assuming too much self honesty. He doesn’t go out and buy a bicycle, he goes out and buys a 4x4 and calls it a bicycle, and says, “This bicycle’s too big.” [laughter]
CHUCK: It’s the same problem.
SANDI: If you’re driving that Humvee, that’s all you can see. You can’t see any further and we have to respect that. So the problem here isn’t -- the teaching problem is that once the code gets so far out of control, many of these techniques don’t really improve. They add complexity instead of removing complexity in the short term for code base that’s out of control. A lot of people complain about the zone because that’s all they can see. So our challenge as people who believe in these ideas is to either help people start out with apps that don’t get out of control. Or to provide techniques where the app is made up of ten, 800-line models can get back into control. It’s a painful road to hoe, to make an app happy and friendly again once all the parts are too big. So I don’t really know the solution to that other than just by helping people one by one because it’s a matter of faith.
JOSH: That’s when you throw everything out and start over.
SANDI: Yeah, the Humvee guy does not have faith in bicycles and teaching him faith, it’s a matter of faith to get them to do all the intermediate refactorings that take them to a better place in their code. So, I have an enormous tolerance for small objects, I love them. And I don’t care that I don’t remember what they do. It does not matter to me. I trust them.
JOSH: Sandi, this is the terrible question and that’s, when do you give up? I mean, when do you look at an app that’s a mess of crap and it’s not just ten 800-line objects, it’s 100 8,000-line classes.
SANDI: The good thing about the mess of crap is very often someone made it work. You can’t change it and it hurts. But they made it work and so you know what the users want.
CHUCK: That’s why we got paid, right?
SANDI: That’s why we got paid because we delivered that software. But it can be true, like sometimes, I advise people to use the user interface and start one feature at a time, one use case at a time writing new code and turning the old code off, or even leaving the old code on, taking the links out. Sometimes the cost of fixing it is much higher than the cost of rewriting it. And I just look for seams in the code where I can break it and it is true. If I think, it would take me a week to figure it out how to change the code. But if I’m willing to eventually throw away the whole app, I can add this new behavior to an existing feature by rewriting the whole thing faster than I can figure it out. Then, some ways, yeah, you cut your losses. You learn something, you move forward doing the best you can.
JAMES: There are ways to handle those big things though, right? Like you introduce a service object and push as much of this one piece behind it as you can, just to guarantee that you’ve got the seam in there.
JOSH: So these are like things that you can do to work around it. The question I asked, though, was -- and maybe there isn’t a good answer for this, but how can you actually evaluate what’s going on in this big mess of code? So you had all of these, you said, “I gave up and told these people these rules of thumb for what to do in their code.” Can you give a rule of thumb for, if your code is this big of a mess, you should give up and start over?
SANDI: I have not been paid to say this, I would say run Code Climate and go to the churn graph and look in the top right hand corner. And if you feel like that glass is costing you money, start refactoring.
CHUCK: Caught object right there?
SANDI: Yeah. It’s like the thing that you check in all the time that’s really complicated. I can promise you it’s costing you money. That may be the only class, that class might be ten classes, right? I mean, you might have to break it up into a lot of pieces, but refactoring that class might be all you need to do in an app. And if that takes you’re pain points away then, you’re good to go.
AVDI: So never give up, never surrender.
JAMES: That’s right!
AVDI: I love that movie…
SANDI: It’s always fixable. And, you know, fixing is fun. It’s enormously satisfying to clean up the mess.
DAVID: A little bit of therapeutic refactoring, huh?
SANDI: Yeah, Katrina.
JOSH: That’s great. Is that a good point for us to switch to picks finally?
CHUCK: I think so. No one seems to be winding down so…
JAMES: Just to be clear, no one has had a bathroom break since this started.
SANDI: I had a coffee.
CHUCK: Oh, oh, oh! Who needs to go first?
DAVID: I have so many follow-on questions but I’ll save them for another call. I just want to say for the listeners, I really am a better programmer than I sound.
CHUCK: Yeah, he’s highly practiced in writing good code and asking dumb questions.
JOSH: Sandi, so we don’t have enough time to talk about everything we want to talk about. Will you promise us that you’ll spend a little time with us on the Parley list and have some conversations there?
SANDI: Yeah, that’s something that I’ve been meaning to do anyway. Here’s the thing, I just find I suck at electronic media. I hate it. I’ve been lurking on the Objects on Rails group thinking, “Wow! That’s a good question.” “Wow! That’s a good answer.” “Wow! That’s a good question,” without ever having jumped in myself.
JOSH: So here’s my pro tip for email lists like that, treat email messages like they were methods. Write a five line email.
SANDI: That would help, because I do. I always feel like I have nothing to say, or a book to write.
JOSH: Just say something short and sweet.
CHUCK: So the last mailing list you joined in on, your response is POODR? [laughter]
SANDI: Read the book, yeah. I’ve been telling people and I probably shouldn’t say this for recording. Because it’s being published with a national publishing company, it means I’m making no money so I can recommend it without a conflict of interest. So yeah, buy and read POODR.
CHUCK: There you go!
JOSH: That’s great. Okay, that’s a good place to stop.
CHUCK: Alright. One other thing, I forgot one announcement at the beginning before we get into the picks. And that is that I am going to be in Las Vegas next week. I will be at New Media Expo where they are going to be giving out the Podcast Awards. We were nominated, so you can watch it live.
JOSH: Thanks everyone for nominating us! [cheering]
CHUCK: Yes, and for voting during the voting. A lot of those shows are pretty popular but I think we have a fairly engaged fan base. So I think we really do have a shot. I just don’t know how good it is.
JOSH: And by the time everyone hears this episode, we’ll know.
CHUCK: Yes, that’s true. But anyway, you can go to PodCastAwards.com and see who won. Anyway, let’s get to the picks. James, do you want to start us off?
JAMES: Sure. My first pick is a link, I believe came up on Parley. It might have been Cory Haines that threw it out, if I remember right, to a video that Michael Feathers did called ‘The Deep Synergy Between Testability and Good Design’. And it’s extremely on topic for the conversation we just had and talks about a lot of the things that we just discussed. Chuck’s question about ‘I have this small public interface’, ‘a bunch of private methods under it’, and ‘there’s difficulty in testing that’. That’s his first example to the ‘T’. So literally, watch the first 15 minutes of this video if you want to know that. But he goes on to a lot of things about how testability and good design are intimately related and it’s a lot like the testing chapter in Sandi’s book. So, great video. Then just some fun stuff. I was on vacation all through the holidays and playing a bunch of games. I found some stuff I really loved. So if you’re a video nut and you like 4X strategy games like I am, if hearing something like, ‘Masters of Orion II’ makes you wistful, this is a great game that’s on steam right now called ‘Endless Space’. And like I said, 4X strategy, a lot like the MOO series. So, if you miss that kind of thing, here’s a great way to get it back. Combat’s a little different but it grows on you. That’s good stuff. The other games I was playing while I was on break were board games. Here’s a list of some of the great ones this year from the Morning News today. What I love about this list is they give you the Top 10 and tell you how those were chosen but then there are some other ‘didn’t win’ and ‘here’s why’. I love a ‘didn’t win’ game because it was too complicated, that’s my kind of thing. So anyway, I’ve played a lot of these games, they’re good - Lords of Waterdeep, Love Letter, Eminent Domain. I was playing a ton. So anyway, lots of good games in there if you’re a big board game fan, those are them. Okay.
CHUCK: Awesome. David, what are your picks?
DAVID: I said I was going to forfeit my picks in the interest of time and I’m going to stick by my promise.
CHUCK: Okay. Avdi, what are your picks?
AVDI: So during my extended transformation into my sandworm form, I found my eyes were particularly sensitive to light. So, I listened to things instead. So I got a couple of podcast picks. First is a single episode of Penn’s Sunday School, where Penn Jillette talks to George Takei. He talks a lot about George’s experience in the Japanese Internment Camps; really, really interesting stuff about a chapter of American History that probably most people don’t know enough about. But then he also talks a lot about his experiences coming out and stuff like that, really good stuff. Also, I listened to a bit of Dan Carlin’s Hardcore History. That’s a fun podcast. Oh yeah, one of my favorite podcasts for a while now on a rare occasion when I find time to listen to one is the Infinite Monkey Cage from BBC Radio. It’s a hilarious Science program. I don’t know how to describe it but it’s really, really good.
JOSH: A hilarious science program. Sounds like a great description to me.
SANDI: I’m signed up!
CHUCK: Alright. Well Josh, why don’t you pick?
JOSH: Okay. In the interest of brevity, I’m just going to do one pick this week and that’s, this is something from the Apple Apps Store and it’s called ‘Marked’. I’m trying to get my business partner to do a more development type workflow around the content that goes in our applications. So, I’ve shifted a lot of the pieces to be able to work off of Markdown. He’s not technical. So, he doesn’t use TextMate and he doesn’t have all the tools to be able to do things, so I found this nice little app that is basically a Markdown preview app. It’s at MarkedApp.com and it links you to the store for apps, in the apps store. But it’s great. You can just, you have this little window up on your screen all the time and then you go in your favorite text editor. I told him to use iA writer because that’s nice and simple and doesn’t do crazy formatting like pages or what have you. But Marked is great. You can hook it up to your own Markdown renderer. So, if you want to use Github flavor for your Markdown, for example, it’ll do that. You can hook in your own style sheets and you can see what things will look like when they get rendered. And this is really great. It’s a nice light way to see what Markdown is going to turn into. It even will just sit there and watch the file. So, you don’t have to switch over to the app and hit refresh or anything like that. So Marked, that’s it.
CHUCK: Alright. I’ll go next and then we’ll have Sandi give us her picks. So my first pick is something that I sorely missed being at my in-laws’ house, and that is my Herman Miller Aeron chair. I had my chair fall apart. I posted the pictures on Twitter. You can go dig back through the archives. It was just before Christmas when it fell apart. Anyway, I got a headrest for it, the whole nine yards. And it’s amazing the difference that a chair will make. I didn’t realize just how much better I feel sitting in a chair that’s built to be ergonomically healthy versus not. So, I definitely love that. The second thing that I’m going to pick is something that I am working on right now and that is that I’m going to be starting another podcast. We’re going to be talking about IOS development. So, if you know people that you want to be on that show, then Email me, email@example.com and we’ll be getting that show together and be talking about that kind of stuff.
DAVID: You need an intervention?
CHUCK: I know. Sandi, what are your picks?
SANDI: So before I give my picks, let me complain that I’ve been on the fence about that chair and you just cost me $850. [laughter]
CHUCK: You’re very, very welcome. It’s amazing the difference it’s made for me.
SANDI: So, I should thank you now?
CHUCK: Yeah, I got the one with the, what do they call it, the lower back support?
SANDI: Yeah, the lumbar.
CHUCK: Yeah, the lumbar support.
SANDI: I might go after this and get it. I really have been on the fence and I need it badly. So, thank you for that pick. I have two picks. One was directly related to my ability to get the book out the door. It’s called BubbleTimer.com and it’s an incredibly simple website that lets you list things that you want to do or don’t want to do and fill in a bubble chart like a school test-taking bubble chart in 15-minute increments. So you can say, “I want to spend less than four hours a week watching T.V.,” or, “I want to spend 15 hours a week working on the book.” And you just bubble off the cells when you do it. For me, for a project that lasts a really long time, it’s really difficult to ever take time off. And being able to bubble in, being able to really simply track time and know that, “Now, I can rest because I’ve done all that I have to do this week. I don’t have to be on it or feel guilty about it all the time.” It was incredibly psychologically powerful to be able to do that. So, I recommend it to everyone who either wants to stop doing something or wants to do a really long term project but feel like they get to have a break now and then, BubbleTimer.com. The next thing is, it’s Fall in North Carolina. So, I got to get my Gutter Cleaning Robot out. And I think everyone should have one. So, I’ll post a link in the show notes. I get to put the ladder up on my house one time and put the robot in the gutter and drive it around. It is really fun. I can recommend it. [crosstalk]
JOSH: You didn’t get the Skynet interface upgrade that let’s the robot get driven by the satellite video?
SANDI: I would. That would be totally cool. Putting a 24-foot step ladder on a two-storey house adds an element of danger that you just don’t want to miss.
JOSH: Been there, done that, nearly fallen.
DAVID: Extreme Housekeeping!
SANDI: Get the robot.
CHUCK: That sounds cool. We’ll go ahead and wrap this up. Thanks again, Sandi, for coming. This is honestly one of the best episodes that we’ve done. It’s just been really fun to talk to you.
SANDI: You guys were fun. It’s been a delight.
JOSH: Sandi, put in one last plug for your book.
SANDI: Practical Object Oriented Design in Ruby. [crosstalk]
JOSH: What’s the website?
SANDI: POODR.info has links that will take to every place that sells it.
DAVID: She embraced the POODR. That’s awesome.
SANDI: Sure. That way, you don’t have to remember whether it’s practical or pragmatic. JOSH: And Sandi, do you have any speeches, you said you’re going to be speaking at BaRuCo which is, I guess, mid-September in Barcelona. Do you have anything else lined up this year yet?
JAMES: Yeah, she’s coming close to me.
SANDI: Yeah. I’ll be at ConFoo in March, first of March. I’m going to Ancient City Ruby in St. Augustine. I submitted to Rails Conf, so I hope to be in Portland. Oh, I’m going to LoneStar.
JAMES: There you go! That’s close to me.
SANDI: I’m giving a keynote at LoneStar so that will be new territory for me. And then, I’m drawing pictures for BaRuCo. So yeah, come see me!