069

069 RR Therapeutic Refactoring with Katrina Owen


The Rogues talk to Katrina Owen about therapeutic refactoring.

This episode is sponsored by

comments powered by Disqus

TRANSCRIPT

JOSH: Katrina, do you know about the picks?

KATRINA: I do. I have like four lined up. If that’s too many, I can reduce it.

JAMES: Not at all.

CHUCK: Four is good.

JOSH: You know 4 picks from you is probably about equal to one pick from David so…

[This podcast is sponsored by New Relic. To track and optimize your application performance, go to rubyrogues.com/newrelic.]

[This episode is sponsored by JetBrains, makers of RubyMine. If you like having an IDE that provides great inline debugging tools, built in version control and intelligent code insight and refactorings, check out RubyMine by going to jetbrains.com/ruby.]

[Hosting and bandwidth provided by the Blue Box Group. Check them out at bluebox.net.]

CHUCK: Hey everybody! And welcome to Episode 69 of the Ruby Rouges podcast. This week on our panel we have Avdi Grimm.

AVDI: Hello! Hello!

CHUCK: David Brady.

DAVID: Hey everybody! In honor of the Mass Effect 3 ending, I’m going to spend the last 10 minutes of this podcast showing you the ultimate way to repair your car! CHUCK: Josh Susser.

JOSH: Here I come to save the day.

DAVID: Yey!

CHUCK: James Edward Grey.

JAMES: According to Twitter, I am the “laughing bird” of this podcast. [laughter]

AVDI: Who is the drinking bird?

JOSH: That would be you!

DAVID: Is that your answer on Jeopardy?

CHUCK: I’m Charles Max Wood from devchat.tv and this week, we have a special guest and that’s Katrina Owen.

KATRINA: Hello!

CHUCK: Since you’re new to the show, do you want to introduce yourself really quick?

KATRINA: Sure. I’ve been doing Ruby for about 2 years. I did this at a small product development company in Oslo, Norway.

CHUCK: Oh.

JOSH: What did you do before Ruby?

KATRINA: Do we have to talk about this? [laughter]

JOSH: No.

JAMES: Oh! It’s shameful.

CHUCK: She lives in the land of the chosen frozen. And she doesn’t want to talk about what she did before Ruby.

KATRINA: So I actually, I can reveal that I wrote PHP for a fashion company in Los Angeles.

CHUCK: Wow.

JAMES: Way to find the pain point right off the bat, Josh. [laughter]

DAVID: I am coming out of the cold but you moved to Norway.

KATRINA: Yeah, I’ve been back and forth a few times.

JOSH: Sorry about that Katrina. Welcome to the show! How are you today?

KATRINA: Thank you. I’m fine. How are you?

CHUCK: Aren’t we supposed to start the show off? Go on. So did you guys do anything interesting this week?

JAMES: The enthusiasm is way too low.

DAVID: That’s right.

CHUCK: No. How about you? Not really.

JOSH: We do that every week. We just edit it out. [laughter]

JAMES: That’s the pre-show.

DAVID: The dirty little secret of Ruby Rogues is we actually record 7 hours of show.

CHUCK: It just takes us 6 hours to get revved up, right?

AVDI: 5 of them is just discussing Firefly.

DAVID: Well, 3 ½ of them are parts of my picks that don’t make it in to the episode.

CHUCK: That’s true.

JOSH: So Katrina, have you listened to the show before? And do you know what you’re in for?

KATRINA: Yes, I have listened to it. Now I don’t know what I’m in for because that is probably new.

JOSH: Okay.

JAMES: Right, now she’s trying to find a way to get off of this phone.

JOSH: So James, since this is your fault, why don’t you set us up for the conversation?

JAMES: This is my fault. I had built up like a long list of videos I’ve meant to watch someday and I’ve just been slowly working my way down that list as I had time. And recently, I can’t remember who recommended it to me, but I watched Katrina’s Scottish Ruby Conf video of her “Therapeutic Refactoring Talk”. And it is an absolutely excellent talk and so I came back on like, “Hey! Guys, you’ve got to see this talk” and asked Katrina to come on to the show. And I think you’ve given that talk, is it twice now Katrina?

KATRINA: It’s three times now.

JAMES: Three times now? Yeah. You’ve given it in multiple conferences and I’ll say that usually I’m pretty against repeating talks but I’d make an exception for this one ‘cause it’s great and everybody should see it.

JOSH: Wow.

JAMES: It’s a good talk.

JOSH: It’s like the movie “Serenity”. It’s actually better the second time you watch it.

JAMES: That’s right. So tell us Katrina, what made you want to do this talk? Why did you do it?

KATRINA: I refactor a lot and I think that a lot of people don’t refactor enough. So that’s one thing. Also is that Ruby just a meet up locally here in Oslo and kind of just pulled up my editor and started showing people little refactorings that I’ve done, sort of before after, just informally, and they were really into it. So I figured I could do something kind of more structured around that.

JAMES: You know, so I’ll confess. How I watch videos is this: I open them up in my browser, I turn them on and then I just take off to do something else. And I’m kind of listening to them and basically it’s either you hook me or you don’t; and if you do, I’ll go back and just really get into it. And at the beginning of the talk, it’s kind of odd, you know, you’re kind of telling them the story and I’m like, “Wow! This is strange. What is this?” And then you really start to get into it and I think you had me at the word ‘method object’ or something like that. And then I really start to pay attention to what you’re doing and went back home and watch the whole thing. It’s very clever. You do it as a story. It’s, you know, this narrative and what made you do it like that?

KATRINA: The first thing was that I really needed a way to pull people in because it’s kind of hard to follow. Or technically, there’s a lot of potential for overwhelm at which point people go off and check their emails and Twitter and whatever. So I needed to find a way to be able to break it up and only do like 7 or 8 minutes of code at a time and I had to find interludes. And I kind of stumble on the story… the story approach especially, so I showed some people, among them, Sandi Metz, an early version of the talk. And some of the feedback that I got was that there’s not enough context, like I’m seeing all these code. I see what you’re doing but I don’t have enough information to know what I’m looking at ahead of time. So I started working on the back story of refactoring and that turned into this whole intro that you see.

JAMES: That was really cool. Another thing I loved about it is how you’re basically doing a live coding exercise, but you do not do live coding. You have it all pre-planned and slides and you show we’re going from this to this. You make heavy use of like ellipsis to, you know, throw out sections that aren’t relevant right now or you bold the line that we need to pay attention to because that’s what you’re messing with. What made you decide to do that instead of just like typing on the keyboard?

KATRINA: So I’m not brave enough to do live coding.

JOSH: That’s a good reason.

JAMES: Yup. That’s good.

AVDI: And for that we all thank you.

JAMES: Yes, we do.

JOSH: “s/brave/foolish/”

KATRINA: So technically, not really. I saw this amazing talk at Scottish Ruby Conf, I think it was the day before… we weren’t on the same day but it was, we both we’re doing a talk about refactoring. Mine was completely, you know, almost like storyboarded and his was live-coded; and it was brilliant. “R00K” (R-0-0-K), Ben Orenstein from thoughtbot. It was an amazing presentation and it was live-coded and it went really, really well. Something that I’ve never actually seen before. So, it can be done.

JAMES: Yeah, it’s possible to get them right. I think it’s kind of rare. It’s really… there’s a lot of places to go wrong.

JOSH: Yeah, live-coding in talks is very much like flying without a net on the trapeze. And I don’t like oing that. The best live-coding I’ve seen done was Nick Kalen’s  talk at Rails Conf, oh god… How many years ago? When he basically test driven development to create the association proxy structure with an ActiveRecord. And that was an awesome talk and I despair the fact that it wasn’t recorded. But luckily we have Katrina’s talk recorded, so we could talk about that instead.

DAVID: When live-coding goes right, it’s trapezing without a net. When it goes wrong, it’s parachuting without a parachute.

JOSH: Yes. And this is the splat operator. [laughter]

JAMES: Yeah. So one more awesome thing you did in that talk and I’ll try to stop gushing but, I’m like a super big brain research geek and I love to read about how our brain works and stuff like that. Here I am watching your talk and low and behold you are going to the why of how we do this refactoring and how it helps our brain and stuff. So, what made you throw that in there?

KATRINA: That’s why I started refactoring, for fun in the first place. I just realized that it made me feel better. Whenever I freak out, I kind of stop thinking well and refactoring was the one thing that kind of brought me back. I started looking into why that might be. I was reading a book called, I think “Choke”. It wasn’t a very good book but it did talk about some of the research around working memory and other things that have to do with kind of freaking out and loosing grip of your current context. So yeah, that’s why. It just, it’s been incredibly helpful and I realized that there had to be sort of a back reason for that.

JOSH: I have question about the Therapeutic half of the talk.

KATRINA: Sure.

JOSH: So the…

CHUCK: What are you trying to say Josh? We all need therapy? Don’t answer that. Never mind.

DAVID: Yeah. We need a good refactoring. [laughter]

JOSH: I definitely feel like there are days when my brain could use a refactoring. I’ve acknowledged that TDD is one of my stress-reduction techniques when I code. You know if I feel like freaking out too much over what’s going on with my code, I write more tests. And that almost always make me feel more confident about my code and I have more awareness of what’s going on and from a psychological perspective, fear is really about concerned that you’re not in control. So if you’re control, you’re not afraid of things anymore. The thing about refactoring that I find sort of emotionally challenging sometimes is that I have to confront the mess that I made. And like any mess that you create in your life, it can be a little confronting. You have to deal with the extent of all that stuff and it’s really nice to see that you can take a big mess and break it down into small pieces that are each manageable and dig in and attack them one at the time and then eventually clean up the mess. But there’s this, I think there’s really a big psychological hurdle to get over when attacking a big mess, especially if it’s one of your own creation.

KATRINA: So I actually really like attacking a big mess. Sort of differently from writing code from scratch in that I don’t have to think about new behavior. All I have to do is make sure that I’ve covered it in tests well enough and that I can go, you know, kind of treat it microscopically. Do one tiny transformation at a time without having to worry about where this code is going; because the code, the behavior is already where it needs to be. CHUCK: Right.

JOSH: Yeah, for people who haven’t watched the talk, I think… Hi David…

DAVID: I am representing those… I am representing an important demographic of our listeners; those of us who are going to watch the talk right after listening to this episode.

JOSH: Or push the PAUSE button now and go…

DAVID: Yeah, I’ll be back in 30 minutes.

JOSH: So that I like that you started with a code base that was not only a mess, but didn’t have tests.

KATRINA: Well, that’s kind of… that happens a lot, right?

JOSH: Sure. If you test, it probably wouldn’t be big of a mess.

CHUCK: I was going to say, where you referring some kind of correlation between the two?

JAMES: So Katrina, can you tell, please, how you did those tests? Because that too is also very clever.

CHUCK: I was going to jump in and say that that right there, you know, I was kind of still working through that in my head through the rest of the talk and then I was like, “The rest of this is so good too. I need to go back and watch it again.”

KATRINA: So they’re kind of classical characterization tests in that whatever is there is right. So you just assume that whatever the code is doing is good. So, I start out by sending in some random input just to see what the method does with it. And I think I just send them in a stub. And then, every time I run the test, it’ll tell me about some methods that are missing on the input and then as, when I finally get all of those messages defined on the stub, then the failure actually tells me about what the output should look like. So then you just kind of copy paste that into the assertion.

CHUCK: Yeah, I have to say I really like that use of mocks or stubs. I don’t know that I’ve really seen them used that way, you know, where you’re kind of using it to reverse engineer the code or to set things up so that you can, you know, test the result of a particular method.

JAMES: It was really cool. It both allowed her to figure out what it was doing, what methods were being called, what results were being generated. Basically, treating the code as a black box and at the same time, she basically uncovers a bug while she’s doing the process.

JOSH: One of the things that stood out for me in that process was how great Ruby is for this sort of process. And if you would think about doing that same process or exercise in a language like C ++, it would be I think much more painful.

KATRINA: There might be a more boiler plate. You’d have to actually have the correct types and everything. The fact that you can duct type pretty much anything and just send in, you know, and they could just stub makes it a lot easier in Ruby.

JOSH: Yeah. The dynamic nature the language makes that sort of code investigation so much easier. So that was fun to watch that part of it too.

CHUCK: Yup and I also, I really like too that you could immediately get a feel for what was going on in there. I mean just by looking at that stub, you could see, “Okay. Well, it’s using all of these information or all of these methods on whatever’s being passed in which is the target.”

KATRINA: Right and one of the things that I didn’t do in the talk but I did in the real code is that I defined some shared examples that just define that API, the accepted messages and then I run the map against the stub and against the original object.

JAMES: That’s a good trick. I just learned yesterday from Sandi Metz, in fact.

KATRINA: That’s where I learned it as well.

JAMES: Yeah, showing how, basically, people eventually complain that you mock the… mock or stub the API and then what happens is if you changed the API, your tests all passed, right? Because your mock still has that old API but it’s passing in so it still passes whereas you don’t get failure. So if you throw it in the module and then put that module and the tests against the actual class and also against the test double itself, then, you can verify that something will break if the API changes. It’s very cool.

CHUCK: As we learned last week, that’s also why you have acceptance test. It’s so that it’s running all the way through front to back and then if API does change and you mock doesn’t, then your unit test will still pass and then you’ll see that there’s something that doesn’t add up in your acceptance test.

JOSH: Yeah. Slight little tangent here, the RR, the test double library from Brian Takita. I like RR or Double R. It’s very thirst in its syntax, which I find pretty nice. But one of the features that it supports is that it will, you know if you’re doing a mock, it will… you can give it, you know if you’re mocking a particular object and wrapping an object, it will actually check to make sure that the object itself also understands the method that you’re mocking out. So that you’re not just like stubbing something without checking to make sure that the thing that you’re stubbing is there too.

JAMES: That’s kind of neat. S basically if you try to define a diameter method but the underlying object doesn’t have a diameter method, it breaks?

JOSH: Yes. Yeah, that’s what you can do.

JAMES: That’s cool.

CHUCK: Yeah. One other thing…

AVDI: Also is the RSpec-fire extension to RSpec.

CHUCK: RSpec-fire? What does that do?

AVDI: Ah. Something similar to that.

DAVID: It’s like regular RSpec only it’s the next model and it’s in color.

JAMES: Plus it’s on fire.

AVDI: It says in checking that you’re mocking stuff that’s actually three.

CHUCK: Okay. So, one other part of the test writing that I really like was that, you know, after you had kind of tested the happy path, you didn’t just leave it there, but you went through and looked into all of the different conditionals and things and, you know, made sure that, you know, all of the different edge cases were kind of handled and all the different things that it was trying to compensate for in one way or another up to and including leaving the square brackets in the name. You know, you made sure that you tested all of that so that if the API did change for whatever reason, then the test would alert you that something was not the way that it had been before.

KATRINA: Yeah. I think it’s really important to have really solid characterization tests when you’re trying to clean up a mess. And one of the things, once you get the happy path, you know a little about the code. You know just enough to not be freaked out by reading the code line by line, so that you can go back and just look at every line of code and say, “Okay. Well here, I’m going to be in one of the lines where stubbing have underscores.” So you know that and then you have to make sure that you are actually, that you have test data that has an underscore in it and so that you can see that happening. And the other thing is conditionals, is that as long as, there is many paths through the methods as you have conditionals, so just make sure that every single branch of every conditional is called from a test and then you know you’ve at least gotten through all the paths.

CHUCK: Right.

DAVID: Do you have a coverage library for that? Or do you…

KATRINA: I don’t.

DAVID: So, just discipline?

KATRINA: Yeah.

DAVID: Okay.

JOSH: Have you heard about… what’s it called? Jeckel? No, Heckel.

DAVID: Heckle.

JOSH: The other crow.

KATRINA: Heckle doesn’t work in 1.9 and I heard that there’s something called metric or metrical or metrically or something like that, but I haven’t had time to test it yet.

AVDI: They’ve been working on a… someone’s been working on a replacement for Heckle that does work.

JOSH: For this listing a long, Heckle was a mutation testing coverage library.

JAMES: So basically, we go through and purposefully modify a conditional to make it not, you know, do the opposite or something which should trigger a problem if you have good test coverage.

JOSH: Indeed.

CHUCK: Yup.

JAMES: So Katrina, you have one other part in the talk that we haven’t really talked about; where you basically coin a new term that I hope spreads ‘cause it’s awesome. And in this part of the talk, you basically spend, I don’t know, however long, 7 minutes or so, just talking about everything that’s a pet-peeve to me. So I just wanted to know how you read my mind like that.

KATRINA: The term code “Codejunk”, I didn’t actually coin the term. Carl Manaster, a developer in Southern California coined the term probably… I don’t know, 3 or 4 years ago I heard him mentioned it; and ever since it’s kind of been riding at the back of my mind. And I keep looking for things that are sort of equivalent to Chartjunk, where it adds noise to the code, where, you know, if it’s there, the code still works, right? But it’s superfluous and kind of ugly.

JOSH: It’s like putting parentheses around the conditional expression in your “if”.

DAVID: So for those uneducated plebes in our audience, can we call for a definition of “ChartJunk”, those of us who are not familiar with Edward Tufte?

KATRINA: Yes. So…

DAVID: Well I, of course have 3 of his books but that’s because I can afford the $300 a copy for them.

KATRINA: Why won’t you find it then?

JOSH: Wait. You have 3 of his books and still you cannot pronounce his name?

DAVID: I have never actually heard his name pronounced. So as near as I know, he’s not a real person. [laughter]

JOSH: Well, he introduced himself as Edward “Tuf-tee”.

DAVID: Edward. Okay. I was going to say “Ed-vard”. [laughter] Because if you read his books, the man, you know the man’s going to have a fuzzy name. So alright, ChartJunk, comes from Edward Tufte who has… just Google him. Seriously. If you have to do any kind of UI work, he wrote… was that Visual Display or the Quantitative Display of Visual Information. Beautiful…

JOSH: The other way around. The Visual Display of Quantitative Information.

DAVID: There we go. There we go.

JOSH: I just read that off the spine of the book on my shelf next to me.

DAVID: Awesome. I can see one Tufte book. It’s actually in the hallway from here. Visual Explanations…

JOSH: We’ve now gotten into the “conversation junk” part of the… [laughter]

DAVID: Yes. This is Rogue’s junk. And basically anytime I’m talking. Anyway, ChartJunk is anything on a graphical chart, which does not contribute to understanding what you are seeing. And so, if you do pretty borders, or if you do background colors that don’t actually contribute to the quantity of data being displayed, this is Chartjunk.

JOSH: So, it lowers the information density of the display?

DAVID: Right. Well it dilutes… yes, it lowers the information density by diluting it. The amount of information is still there, but there’s more things assaulting your senses visually. I guess your visual sense. And so, it dilutes the quality of it. There’s one fantastic chart that somebody did of a Wall Street ticker chart and it was of some… like the vice industry I think and it was, and it spiked up and it had gone down and it had ticked back up just a little bit. And so the person drawing the chart drew in a woman’s leg in fishnet stockings to demonstrate that this is a chart about prostitution in New York City. And Tufte spends an entire page blasting the fact that somebody took the time to draw a leg on this chart because it has NOTHING to do with the actual data. And then because this got spent so much time drawing the leg, they didn’t actually bother to put like the units on the left-hand side of the chart. So you have no idea, you know, and so the dark side…

JAMES: Units of legs, obviously.

DAVID: Yeah, units of leg. Yeah, so this chart approximates one leg. Anyway, to wrap up, this is what… I’m just fired from giving definitions from now on. If you do a job badly enough, you won’t be asked to do it again. So, the dark side of Chartjunk is this and that is that you can, anytime you have a chart that does not have enough information, a weaker wield person than Edward Tufte will always be tempted to tart it up a little bit with some Chartjunk to make it look like there’s more stuff there. And in the case of the woman’s leg… literally tarting. Codejunk then, by analogy, is anything you stick into your code that reduces the information density of what you are seeing. Well, I should have just said that and been done and but I’m incapable of it.

JOSH: Can we get the VA to just like condense that entire thing? [laughter]

DAVID: Just take the whole section and play it at hamster speed. I would have just said the last sentence first, but I didn’t know it until I’d actually walk through the story. That’s how my brain works. Sorry.

JAMES: That’s awesome. Go ahead Avdi.

AVDI: I said what’s your favorite Codejunk?

KATRINA: Who? Anyone?

AVDI: Sure! Anyone!

DAVID: But not me.

CHUCK: Are there recyclables in Codejunk?

KATRINA: What’s that?

CHUCK: Are there recyclables in Codejunk?

KATRINA: “Recyclables”?

CHUCK: No?

KATRINA: No.

JAMES: There are things you should throw away.

KATRINA: Yeah. You should throw away trailing white space.

JAMES: Yes.

CHUCK: Yes! Like everything you say I was just like, “Yes!”

KATRINA: So I actually had one at Nordic Ruby that I didn’t include afterwards. That’s explicit returns.

CHUCK: Yes!

KATRINA: So this is a religious issue. It turns out some people love it, some people hate it.

JAMES: It is?

KATRINA: Yeah!

JAMES: Yeah, but the other side’s wrong.

CHUCK: This is not Java.

KATRINA: So I took it out ‘cause that’s not the point. I don’t want to get into religion. I just wanted to talk about things that are definitely junk.

JOSH: So the explicit returns thing, I want to talk about that for a few moments.

JAMES: Yeah.

JOSH: Well, we’re talking about refactoring and the reason, the number one reason why I do not like explicit returns is that they offend my eyes. It’s all these explicit code. No. I think that a guard statement at the beginning of the method that, you know, has returned nil unless user.name, or…

JAMES: Or just return unless, which is the same thing.

CHUCK: The purpose is different. It’s not about, you know, anyway…

JOSH: Yeah, right. So, that is a separate case and I think that that’s fine. The thing of that once you get into the body of the method, explicit returns do nothing for you except prevent you from effectively refactoring the code in certain ways.

JAMES: Right, because if you move it, then you’re moving the return with it, which means you’re actually moving effectively a junk, right?

JOSH: Well, yeah. Right and if you copy that thing out and put it in the middle of some other method, or extract that thing into a different method, it’s not going to be able to return out of the middle of your other methods; so, you have to change around how the code is structured.

AVDI: Right. One of fundamental rules of refactoring legacy code is you want to be, you know, you want to be able to make changes with the smallest change possible. Like, you want to be able to, as much as possible, lift code from one place to another. ‘Cause one of the objections that people might come up with is, you know, well, go through it and change all those returns. But you know, where refactoring efforts tend to go south is it’s in the one more change. You move some code and then you realize you need one more change, then you need one more change, then you need one more change. And pretty soon the project’s on the floor, nothing works and you wind up blowing away your branch and, you know, throwing away your work.

KATRINA: Right, by definition, that’s no longer a refactoring either.

AVDI: Right.

JAMES: It’s also just difficult when you’re reasoning about the method. If the return sometimes is buried in the middle, it’s very difficult to reason about it sometimes.

AVDI: Yeah. Surprise return! [laughter]

DAVID: Return by surprise. Yeah.

AVDI: Yes.

CHUCK: I think I’m going to alias return to like F or something and then F something. Anyway…

JAMES: Alright. So, we’ve settled it. We’re right. The other side’s wrong. [laughter]

CHUCK: Just not leave a comment.

DAVID: If you return out of the middle of the method, then the first half of the method was probably not well composed with the second half of the method. The first half was doing something to get ready for the second half of the method, which means you’ve got two methods there.

CHUCK: Yeah.

JOSH: Yup.

JAMES: Alright. So Katrina, tell us about other things about refactoring. What else about refactoring do we need to know?

KATRINA: So, something that I didn’t cover in my talk is how do you get started. I think that’s a really interesting topic. A lot of people are…

JOSH: Do you mean trying refactoring at all or on a particular case?

KATRINA: Like when you have this code base that is a big ball of mud, how do you approach it? Like you know that there are thousand kilometers to go until this thing is beautiful, but what’s that first step? And I obviously don’t have a whole bunch of answers. My favorite way of getting started is go pick something easy. Really, really tiny and really, really easy.

DAVID: Mh-hmm.

CHUCK: Yup.

JOSH: Now, what do you gain out of starting something small?

KATRINA: Confidence. You start learning about the code just a little bit and every time you refactor something, you’ve understood something more. It’s like a mathematical proof where, you know, for every step of a proof, you have to build up that understanding and the whole proof won’t fit in your head unless, until you built up every single step of it. And then a refactoring will help you understand the code in kind of the same way.

JAMES: Yeah, that’s what I was going to say too. Its understanding. We’ve talked about these last 3 quick, the GOOS episode, but you don’t change the error message of a test just because you can, or because you’re being tedious or whatever. It’s to prove that you understand why it’s failing, right?

KATRINA: Yes.

CHUCK: Yup. It’s all about that feedback and communication again to, you know, like James said, you change the messages because it helps you understand the code. It helps you understand the test and stuff rather than, you know, the other way around. But anyway, you know just changing it just ‘cause you want to change it.

JAMES: Plus a lot of it is, you know, if you start with one thing, sometimes, you know, it’s a bunch of things tied together and you can’t really see the forest or the trees or whatever. And you don’t really know where things belong but if you just start somewhere and you do a little something, like Katrina’s example, she uses a method object in the refactoring. And I remember back where we were talking about to Kent Beck about small talk best practice. He talked about how one of the great things about method object is it always seems a little weird when start doing it, but usually you find what it was giving you is that other place you need to hang methods. And once you got it out there, then its like “Oh yeah! There’s this thing. And that goes over here.” It gets you started, right?

JOSH: Now, okay, so you start off by taking these baby steps, wiggling away little pieces. May be it’s the equivalent of like polishing the chrome on the bumper. How can you tell you’ve reached the point when you’re ready to open the hood and start working on the engine?

KATRINA: Well usually you’d see something. You recognize a pattern that’s almost there or you see that you have… you recognize an abstraction that you’re missing and then you can start building up that abstraction separately may be, and slipping it into the code in more and more places. It’s usually this moment that you start recognizing things. You don’t have to go looking for, sort of desperately searching for a refactoring. You just start with the obvious sort of low-hanging fruit and larger refactorings will present themselves.

JOSH: Okay. So, I love what you just said there about identifying a missing abstraction and that, I think that’s a piece of refactoring that is at a higher level than what most of the refactoring books talk about.

KATRINA: That’s right.

JOSH: Yes. So, is there more to say about that? Or is that you’re just let that stand? So we talked about refactoring as the process of improving the design of existing software.

KATRINA: I think identifying abstractions is a huge part of any refactoring, but it can, I mean there are differences in degrees. Like sometimes you’ll just have all these little, you know, hash that you’re kind of passing around and you realize that what you really want is this object that you can put behavior into. But it doesn’t have to be a very big object. It might just have 2 or 3 methods. And other times, it’s this sort of core idea in your application that you’ve been glossing over or ignoring or that you can spread out in a lot of places.

AVDI: I just had somebody ask me this last night. They were asking me how do I recognize the abstraction to move towards, looking at a piece of legacy code, how I see the code that could be there. And it’s a tough question for me. I mean the best that I could come up with was, if you read more the refactoring literature, you know, things like the Refactoring Ruby book or even like Working Effectively with Legacy Code, you can at least start to get like a sort of a list in the back of your mind of the kind of transformations that are possible. And that could help a little bit in seeing what could be but that was the only answer that I could come up with.

JAMES: So I have an answer there. And mine would be that, as you improve the code and you make it more “well-factored”, it tends that you’re passing more objects around. And I often find that that’s what tips me off. Its like, “Oh! I passed this object in here and I passed this object in here.” And basically, that’s this other concept is pretty much the same thing. Notice how I’m calling the same methods on it all the time or whatever. Sometimes I can notice it in my tests because I build some double to shove in there, right? And that double because I’m passing that around, a couple of different places, it tips me off that there’s another concept there, right?

KATRINA: That’s a really good point. Having to build up a bunch of like, having a huge amount of setup code in your tests is usually a sign that you’ve kind of taken too big of a bite. That you’re trying to test too large of an abstraction at once.

CHUCK: So one other thing that it is sort of related to what we’re talking about here, is what we’re talking about refactoring our code but in a lot of cases what I wind up getting to is, you know, I have a reasonably well-factored application and a set of functionality in there, but my tests are the things that kind of get out of control. Is there a good way of refactoring your tests so that they behave the way that you want them to, take out the craft, and things like that?

KATRINA: Time and patience my friend, time and patience.

CHUCK: Yeah, how do you identify the areas that you need to change, fix or whatever?

KATRINA: Well if your tests are kind of boring to read because they keep repeating themselves or if there’s a lot of setup, or just a lot of kind of boiler plate. You know comparing sort of same sets of values over and over again. I use RSpec a lot. I really like how it’s possible to build up this sort of nested contacts where you slowly build up more and more complex structures but it’s still really easy to follow. I don’t know. Does that help at all?

CHUCK: It helps some. I mean, it’s just I mean a lot of the times you’ll make changes to the code and it’ll break some of the tests then you have to go, you know. You wind up refactoring it because you either understand the problem better or some requirement has changed and you didn’t account for it in everywhere in your tests. But at the same time…

KATRINA: Right, or…

CHUCK: No, go ahead.

KATRINA: No, or the tests are just kind of echoing the implementation and they’re going to break no matter how you change the code.

CHUCK: Right.

JAMES: Right.

JOSH: Okay, so people the Red/Green refactor cycle, right?

CHUCK: They know it. A lot of people don’t do it. A lot of people it’s “red/green what’s the next feature”? [laughter]

JOSH: So we will red-green next feature to red/green refactor, that I saw another chart on a wall of an office that said, Red/Green Refactor, Refactor Tests.

KATRINA: I think the RSpec books actually says that but the refactor step includes both your code and the tests.

JAMES: Yeah, I believe it should include the tests too.

DAVID: There was a big eye opener for me. You mentioned a few minutes ago that, you know, sometimes you have these tests and all these setup, setup, setup, setup where you get 20 lines of stubs and mocks and it becomes really hard to figure out. My goodness! You’re like engineering this whole system. Why are we doing all this work to the setup? And somebody pointed out to me, they walked me through all the mocks and stubs and then they pointed to the code and said, “That’s duplication. You’re actually duplicating all the setup that this method has. So, start extracting.” And it was really hard to figure out the first time and it’s still not easy but it’s getting easier. The more I see it, the more I‘m like, “Oh! Yeah, I need to make all of this setup go away and test this in isolation.”

CHUCK: Right.

JAMES: Right.

CHUCK: Right. That makes sense. So it’s an indication that you have too much glommed on to a single method or object.

JAMES: Right, or too many dependencies that it’s, you know, pulling from that are too magic because you happen to mock them all out or whatever.

CHUCK: Right. So, one other thing that really struck me in the talk was that a lot of the refactorings, if we go back to the Codejunk, a lot of it was just about making it easier to read.

KATRINA: Absolutely.

CHUCK: And it really struck me, I mean a lot of times we talk about refactoring, you know, when we’re trying to optimize it for performance or where we’re refactoring it because it doesn’t fit our style or it doesn’t fit the style guide that we have for our code for that project. And I thought it was really interesting where it was, you know, “Look! You know, refactor it so that you can really bring the meaning to the forefront.”

KATRINA: Well, I was going to say a bunch of times the next time you have to go in there and understand what’s going on.

CHUCK: Yup.

JAMES: Yeah, I hate to go back to it again, but it was really small talk best practice patterns have drilled into my head when in the introduction; it talks about how code’s number one purpose is to communicate with the reader. You know, and everything else comes after that. Yeah, it should do its job, it should be performant, whatever. But the number one thing it you should do is communicate with the reader. That’s why we have code. We read it. We change it.

JOSH: Otherwise, we would be programming machine code.

JAMES: Right, exactly.

JOSH: Katrina, I have a bit of a background question for you. I notice in your talk that you pronounced call-a-method, send-a-message which…

JAMES: Which is the grammatically correct pronunciation. [laughter]

JOSH: Thank you James. Yeah, I did a whole like talk at Steel City that that was the entire talk. It’s not calling a method, it’s sending a message. So, I’m curious a little bit about where are you OOP skills. Did you spend time during small talk? Or where did you grow up during your OOP programming.

KATRINA: I wish I spent a lot times doing small talk. Actually, biologist by trade, geneticists.

JOSH: Oh cool!

KATRINA: So I didn’t do any programming until I kind of just fell backwards into it and couldn’t get back out. I read a lot and there’s something that struck me about how the program is, the real program is when it’s alive. It’s when it’s sending messages. That’s your application. The thing that you type is sort of this dead construct and this is one of the reasons why it’s so hard to debug sometimes it’s because, there’s this sort of dissonance. There’s this cognitive sort of gap between the application as it’s running, as it’s alive and breathing and the code that you’ve written. And sending messages is what the application does to me in my mind.

CHUCK: So, it’s like real cells, sending real messages to…

KATRINA: Right.

JAMES: Which is the goal of object oriented programming, right? Cells sending messages.

CHUCK: There you go. You heard it from the biologist.

JOSH: Very nice.

CHUCK: So one other thing that I wanted to talk about that really struck was you were talking about, well it was when you were refactoring that, building that file name and you pointed out that all of the, like a lot of the lines were, you know, file name and then the chevron to, you know, stick something else on the end, to append something.

JAMES: Yeah, that’s one of the kickass parts of the video, isn’t it?

CHUCK: Yeah, it was really good and it was super easy to follow, but the thing that really struck me was that, you know, you immediately pointed out the things that were not the same as the rest of the method. And it really struck me that there is kind of a shape to the code. There are different sections to each, you know, way of solving the problem. And it just totally jumped out of me. I still have this slide that you had in your deck that keeps coming to mind and it’s literally just this rectangle with nothing in it, nothing around it. And you’re saying this section of the code right here is the part that’s a little bit different from everything else, where it’s not just jamming something on to the end of that file name. And you know, you’re like, “So this is a good candidate for…” I think you extracted a method there or something. You know, for me it just really, I don’t know why but it was so visually compelling to me to just look at it and go, “Okay, so there is a shape here. There is a form to this code that if you really look at it, you can start to pick this apart without actually reading the code”. Does that make sense?

KATRINA: Makes a ton of sense. It’s one of the heuristics that I use when I’m trying to approach code that I don’t really know ‘cause beautiful code is often very regular. It has a rhythm to it and you can sort of follow it. It’s not jarring. So one of the things that you can do is just look for the irregularities and try to remove them.

CHUCK: Yup.

JAMES: And I find that to be a very right brained explanation of a concept that I think of than left brain which is the same level of abstraction. Everything in the method should be at basically the same level of abstraction. So if you’re seeing those different shapes, that’s a hint of that’s not happening, right?

KATRINA: Exactly.

JAMES: It’s that they are in different levels of abstraction. You in that video, Katrina, you liken that to some child’s game I think. And I didn’t get the reference.

KATRINA: So, I don’t know if it’s common in the States. In Norway, they have a game called “5 Differences”. It’s actually translated as “Find 5 Errors” and it’s often like a cartoon drawing and we’ll have two versions of that cartoon drawing next to each other and you have to find the… you know, where the hat is a little bit bigger, and there are two flowers instead of three, and things like that.

JOSH: Okay, I think Americans know that from reading the Highlight magazine.

JAMES: That’s right. That’s what I was going to say.

JOSH: Like in a dentist’s office.

JAMES: Yeah.

KATRINA: Norwegians know this from reading Donald Duck cartoons when they’re small.

CHUCK: Nice. But yeah, it’s definitely spot the differences.

JOSH: So, there’s an analogue to what you guys are talking about in actual architecture of buildings and that’s where you have a repeating motif. And a lot of architectures really about figuring out what kind or repetition you want to put in place. So you have a Column A, then you say, “Okay. I want to put a column every four feet. And then every eight columns, I want to put an archway”. And you can build, you can just, you keep doing this and repeating things and eventually you get the coliseum in Rome where it has a whole bunch of repeating elements. And the regularity of the small repetitions gets sort of bundled up into the larger scale.

KATRINA: So, I have the small abstractions and the larger abstractions.

JOSH: Yeah, so you say, “Oh! That’s three stories tall.” Because you can find out where the stories are if you didn’t have, you know, some regularity how you move from one floor to another. You wouldn’t be able to see that. It could all be a big mess. So, I think that I loved what you did in that refactoring where you took things that were a couple different levels of abstraction and you showed how you could tell that they were in different levels because they just didn’t look the same.

JAMES: Yeah, it was awesome. I agree.

CHUCK: If you’ve seen Harry Potter then you know that my code looks like the burrow. Anyway, we need to get to the picks sooner. Are there any other aspects to this that we want to talk about before we wrap this up?

JOSH: I have a question again on the therapeutic side. I think we’ve seen, you know, we can do this therapeutic process. We have some messy code, we go through it. We feel better at the end. What are the other things that you do Katrina to deal with sort of the… you know, the other challenges in code? Basically like what are your other therapeutic tricks for dealing with problem code, beyond refactoring?

KATRINA: So beyond refactoring, my other trick is step away from the computer. Go for a walk.

DAVID: Whoa! Whoa! Whoa! What?! [laughter]

JOSH: Define “away from the computer”?

KATRINA: I know. It’s really, really challenging. It’s a lot harder than refactoring.

DAVID: Is this far enough??

JOSH: No David, keep going.

CHUCK: Put your hands up and step away from the computer.

DAVID: How about now?? [laughter]

JAMES: It’s hard though, right? It is hard. I get that bit in my teeth and I can’t let it go. I’m going to find this bug but she’s right. Like, I can either sit there and plow straight through for 2 hours and get it, or I can leave for 10 minutes, I’ll be out there talking to my wife and the answer will pop into my head.

DAVID: Yeah. That’s actually a brain rule. The worst thing you can do for your brain is to sit in a chair for hours on end and if you…

JAMES: You’re saying something?

DAVID: Yeah its… [laughter]

CHUCK: We’re all a little slow, but we all got it!

DAVID: I’m done. No, but seriously, if you want to add literally like 30 points to your IQ or to your executive function, get physical exercise. Get your, you know, get some cardio moving. And so, not feel awkward.

JOSH: David, that’s a great point but, you know, I think the “change in perspective”. Is that what you’re talking about Katrina?

DAVID: No.

JOSH: Katrina, were you talking about changing your perspective? Or you’re just like go get some air and wake your body up?

KATRINA: I was not talking about physical exercise. I was talking changing perspective, but I do see how little bit of extra oxygenation to your brain could help.

JAMES: Yeah, it really does help just to get away from it. It’s funny how freeing it turns out to be for your head. It’s not, what finally made me good at doing it is realizing it’s not giving up. Because my brain’s going to sit there anyway. So, I’ll get it later.

JOSH: I think it’s pretty, you know, everyone on the planet except me just watched the Olympics a couple of weeks ago. (I have a tradition of not watching them). But the…

CHUCK: That’s a pretty easy tradition to follow I think. That’s a whole lot less effort.

JOSH: Yeah, but if you watched these top performing athletes, if they give something a shot and they don’t make it, they don’t jump back right at it. They take a moment to catch their breath and then try again a few minutes. So, I think that that’s same thing when you’re banging your head against the keyboard and can’t figure it out. Taking a break, going and playing a game of solitaire for five minutes or reading XKCD or something like that. Just get your brain out of that rut so that you can come back fresh. It’s a big help.

KATRINA: So, there is a kind of difference between this type of intense mental creative work and the purely physical, (or not purely physical I guess), but the achievements that athletes have. In that the type of automation so we need to program and do these very intense sort of structured problem solving tasks. We need working memory. But working memory is not as necessary in these physical tasks. What you need to have is the ability to have to internalize the movements that you need and get your brain out of the way, if that makes any sense.

JOSH: It does to me. The second part there though, getting your brain out of the way, is like so huge. I’ve been doing Yoga for 25 or so years and I figured out pretty quickly in my Yoga other career that it’s mostly about what’s going on inside my brain. It’s not really as much about what’s going on in my body. And if you talk to the top performing athletes, it’s all about getting your head in the game. It’s not about how, you know, the difference between winning and losing an Olympic swim meet isn’t so much about the state that their body is in. It’s about the state their brain is in and how focused they are in the task and how will can they apply themselves.

JAMES: Right, and to human analogy that’s not athletes, I love to go watch my Philharmonic symphonies and stuff and when they bring in a guest artist, I love the artist that are totally into the music so much that they’re swaying and their heads rolling back and forth. And it’s just like you can tell that the music is just like all in them. And that they are applying every sense they have to it and that’s how they’re just, you know, putting their self in that frame of mind. It’s really cool.

CHUCK: Yup. Alright, well let’s get to the picks. Avdi, do you want to start us off?

AVDI: Sure, so for programming related pick, I’m going to go with the book “XUnit Test Patterns” by Gerard Meszaros. This book is about a foot-thick and I cannot claim to have read all or even most of it. But, I have been finding that it’s a useful reference to have around just because it’s the most complete attempt I found to build kind of a full vocabulary around unit testing; which means that when I’m working with people and they ask, “Well, so what’s the difference between the integration test and a functional test?” or something like that. I can look it up in XUnit Test Patterns and I say, “Well, XUnit says this…” and it’s just, and then it also has a lot of definitions of both common patterns and also common anti-patterns in testing and how to address them with better patterns. So, pretty cool book. I’m looking forward to digging into it more over probably the course of the next several years. For a non-programming pick, I’m going to pick the Mei Tai Child Carrier. I don’t even know what that term is. Anyways, there are many, many different technologies for strapping a newborn or an infant to one’s body. You have Snugli and you have Moby Wraps and you have your fancy nylon contraptions and there are slings. I have been using a Mei Tai which I’m going to have to look up the spelling of that. And it’s been one of the more comfortable ones I’ve tried and it’s been pretty sure fire for putting the newborn to sleep. So I’ve been pretty happy with it. For parents out there, there you go.

CHUCK: Awesome. David, what are your picks?

DAVID: So, I have this time on our tradition of helping those of you who listen to the show while commuting get ten further miles down the road during my picks. And it’s actually kind of bugging how long I take for picks and Katrina said that she has four picks today, so, I’m going to, in a surprise stunning move. I’m going to yield my pick time to Katrina and I’m done.

CHUCK: Okay, Katrina, what are your picks?

AVDI: You’re supposed to say, “the chair recognizes Katrina”. [laughter]

KATRINA: My first pick is Zed or Z, the letter “Z”. It’s a shell script that helps you navigates your file system by frequency and recency. So it’s kind of like the Command-T plug-in for Vim or Textmate, except you don’t get fuzzy search. It’s really, really helpful. My second pick…

CHUCK: When you said the letter ‘Z’, I was thinking, “Oh! We’re back to Sesame Street.” [laughter]

DAVID: This episode has been brought to you by…

KATRINA: My second pick: Practical Object Oriented Design in Ruby by Sandi Metz. It is about to be released, like in the next couple of weeks, it should be out. And you absolutely, absolutely should go read it.

JOSH: Yeah, a little, little secret preview here. We’re going to have a few copies of it on hand to GoGaRuCo.

KATRINA: Awesome.

JAMES: We don’t have any tickets, so don’t ask. [laughter]

KATRINA: My third pick, also programming related is another book called “The Little Schemer” by Daniel Friedman and Matthias Felleisen.

JOSH: Oh yeah!

KATRINA: It’s such a good little book. Like if you’re having grocking recursion, this is the book you need to read. And you need to read it with a pen and paper, like don’t just read through. Answer all the little questions. It’s beautiful. And my fourth pick is shameless, what’s it called…

CHUCK: Self-promotion?

KATRINA: Self-promotion, yes. So, I work at this part of the development company in Oslo and they’ve been together for like 17 years. And they’ve been reading wild and crazy, wonderful things and a few years, back when Rails was like 0.8, so sometime during Beta, they started writing web applications in Ruby and by the time I joined, they were seriously feeling the pain of gargantuan, monolithic, tangled rails application. So ever since I started, we’ve been experimenting with writing some sort of more modular, smaller services and then building application on top of that. And in the past week or so, we’ve been started working open-sourcing some of our modules and so pebblestack.org; which by the time the show goes live, should have something up and open-sourced.

CHUCK: Awesome.

JAMES: Sweet.

CHUCK: James, what are your picks?

JAMES: Well, since we’ve mentioned Sandi Metz a couple of times, I’ll start with a pick from her. She did a Lunch n’ Learn at Hash Rocket a little while ago and they just put the video up and it’s a discussion about the different kinds of tests, what you test, where do you do that, where you do the mock, dependency injection, all of that. It’s really good and I’ve bundled up in like a 30-minute package. So it’s a great little talk and everybody should go see that. And then for a non-code pick this time, I have been reading “The Rational Optimist”, which is a pretty interesting book. A lot of media and stuff would have us think things are always, you know, getting worse all the time and stuff like that. But it’s pretty easy to prove that actually things are steadily getting better and better and this is a book, you know, well first proving that and then why is it happening. So it’s a good book. Kind of a good, you now, counter some of the negativity that’s out there all the time which I’m always for. So those are my picks.

CHUCK: Awesome. Josh, what are your picks?

JOSH: Okay, I have like a huge list of picks that I’ve accumulated over the last couple of weeks so I’m going to select the couple of the good ones here. So my first one is Google Web Fonts. I was putting together a page that I wanted to look really great, have a lot of good visual design appeal and the designer is working with this like, “Hey! Let’s use a web font.” And I’m like, “Oh! That’s going to take too long.” And then I take a look at Google Web Fonts and realized, “This isn’t going to take too long.” And we tried it and took me literally about 4 or 5 minutes to completely change how awesome my page looked. And if you’re doing anything with design, I think that it’s really time to start looking at using web fonts. Google has a bunch of really nice, solid, free fonts that you can use and there’s some other companies that are doing commercial licensing of web fonts. Typekit is a good one but I didn’t actually get a chance to play with TypeKit, so, I’m just going to pick Google Web Fonts and that’s that. The next pick that I have is a set of math videos from, I think it’s pronounced —. And she just does an amazing job of making math really interesting and aesthetically appealing. And I watched one of her videos about Parabolas and it was just like this beautiful poem about mathematics. So if you have any appreciation for math, these are really fun videos to watch. And then the last thing is an iPhone app called “Chirp”. I think a lot of people were using bump application a while back where you could exchange business cards just by like fist bumping while you’re both holding your phones. And the fist bump is the handshake. So Chirp is like that, the handshake is an audible bird chirp, so you could hear this (bird sound). And the good thing about it is that it’s not just for only one, it’s one to many. So if you’re standing around with a bunch of friends and just took a photo of everybody, you know, you can just, if you pull out your phone and you use Chirp and you send out the audible tone, everybody standing in a few feet of you, their Chirp application hears it. And then you get the picture transferred from your phone to all of their phones at the same time directly through the server.

AVDI: So it happens every time James laughs? [laughs]

JOSH: Yes, the image goes directly from his brain to the server and onto your phone.  And I think they’re going to be expanding to be able to handle more types of data that they can handle. But I found it pretty handy. I was like hanging out with my family and taking pictures of the kids running around and it was much easier to do that than to try and figure out some other way of sharing. So, it’s worth checking out. Okay, so that’s it for my picks.

CHUCK: Alright. So…

AVDI: Can I tag a quick pick onto there?

CHUCK: Sure.

AVDI: There is this site called Font Squirrel, fontsquirrel.com. They basically list many, many freely available fonts and you can go to any, it’s Google Fonts and other freely available fonts and you can go to any of them and they will give you exactly the code you need to drop into your application to source those fonts. It’s just a complete no-brainer, which I found them really handy.

CHUCK: Alright.

JOSH: Cool. I’ll check that out.

CHUCK: Alright. So my picks, the first pick, I tend to avoid political or religious type things on the podcast but I had kind of a major personal breakthrough and it was due to a podcast. And this is very, very religious thing but for me it was a huge breakthrough. I was listening to this podcast; it’s by my friend Cliff Ravenscraft. It’s called “Encouraging Others through Christ” is his podcast. And he interviewed another preacher named Steve Brown and they talked about a whole bunch of stuff. I’m not going to go all of the major things but if you are religious and you’re looking for just, especially Christian and you’re looking for kind of that something that will help your connection to God; then, I highly recommend you go check it out. You can listen to the episode at gspn.tv/threefreesins, and it’s the word “three”, not the number “3”.  But anyway, that’s just one pick. I just really had this personal thing and, anyway, it really helped me kind of come to terms with some things that I was dealing with. So I just wanted to recommend to pick that. The other one that I want to pick is, it‘s a book by Chris Biligo. It‘s called “The $100 Startup” which is kind of an interesting book for kind of bootstrapping your own little business. He’s got another book or two out there. I don’t remember what they’re called but this one’s just a really interesting take how to build products and how to start a small business. So if you’re interested in that kind of thing, you can go pick the book up on Amazon. It’s pretty interesting. Anyway, those are my picks and well, we’ll wrap that up. If you are interested in hearing some interesting conversations that we’re having, I think we had a whole thread on like parentheses and stuff on the Ruby Rogues Parlay list.

DAVID: Codejunk.

CHUCK: Yeah. It was really interesting but yeah, it really did kind of fall in line with that. Anyway, we’ve got all kinds of interesting stuff that we’re talking about on there. So if you want to sign up, go to rubyrogues.com and sign up. It’s over on the side bar. And our next book club book is “Service Oriented Design with Rails”, something like that by Paul Dix. I’ll put a link in the show notes and you should be able to pick that up as well. Are there any other announcements that we want to put out there before we wrap this up?

JAMES: Can we just say thank you to Katrina for the video and coming on the show.

DAVID: Yeah.

CHUCK: No, we can’t.

KATRINA: Okay, never mind then.

CHUCK: No, thank you Katrina. It really was good and honestly, the video? We’ll put a link to the show notes to that as well. I watched the Cascadia Ruby Conference version and it was just excellent.

JOSH: Yup. Katrina, do you have conferences schedule coming up?

KATRINA: Yes, I do. I’ll be speaking at Frozen Rails in, at the end of September and RCamp in Belgium in October, and then there’s one more but it hasn’t been announced yet in November.

JOSH: Okay.

JAMES: Sweet.

CHUCK: Awesome. Alright, well we’ll wrap this up and we will be back next week.

x