 here this week. This talk is called Mastering the Ruby Debugger. I like the safari name better because I'm not going to teach you to master the Ruby Debugger. First of all, let's do a quick survey. How many people here use the Debugger in Ruby? Okay, very much. How many people here have never used the Debugger in Ruby? Okay, not successfully. Okay, that's cool. Turns out the Debugger is pretty cool. And the reason I'm giving this talk is all because of some conversations that happened on Twitter. But before we get into that, I want to give you a quick review of a little game that I used to play in high school called Black Box. Yeah. Okay, you remember this? You one player secretly puts some marbles into this grid of this 8-byte grid, and the other player will probe the box by sending in signals from the side. And you can get a hit. You can get a bounce like that. You can get a double bounce where it reflects back out. You can get a immediate reflection of the things on the edge, or you can even get a reflection from two things like that. And of course, you can always go straight through or you can get some kind of weird passing going on. Now remember, the second player that's doing the probing doesn't know where those green dots are. So to him, the board will look something like this. Now, if I have more than half an hour, we'd actually play this game. I would let you probe. And I would tell you where the signals came out the other side of the black box. But here's a previous game that we saw that we had played. And you can see here, here's A. A went straight through. C, however, did a bouncing thing right there. So maybe there's a little green dot here, or maybe there's one of those complex paths. You don't know. You've got to keep probing the black box until you find the solution, which in this case is just simply this. Turns out this game is a marvelous metaphor for debugging, because our program has some internal state that's not immediately apparent to us. And we have to figure out what it's doing by observing it from the outside. Debugger, or the tools that we used to do debugging allows to get into that internal state and do some direct observing rather than just observing the outside effects. So debugging allows you to quickly zero in on that. Now, I mentioned there was a little controversy about the debugger, and I'll start with this group. You may have heard of them. Couple months back, they put on a show where they talked about styles of debugging, and amongst the panel, 100% of them did not on a regular basis use the Ruby debugger. Now, people listened to the show, and what they heard was that good developers don't use the Ruby debugger, which of course created all kinds of Twitter controversy, right? Now, to be fair, these guys didn't start this. I started it. Back in October of 2007, if you can see this, I was teaching a class on test-driven development. And in that class was Giles Buckett. Anybody know Giles? Yeah, okay. He's a character. Very good. That's a good way to say it. He wrote this article after the first day of class, and he said debugger support is considered harmful. He said things like Jim Martin, people ask him about the inaccuracy of the debugger, and his response was what debugger? Because at the time, I had never even used the Ruby debugger. I didn't even know there was a debugger at that time. So when they asked me about the debugger, I said, I never use it. I don't know about it. So Giles wrote up this article. He said things like asking why Ruby has a weak debugger is like asking why a dolphin doesn't have gills. Ruby has weak debugger support because Ruby programmers shouldn't be using a debugger. It gets better. Okay. And surprisingly, he was surprised by the feedback he got on this article. I can't imagine why he was surprised. Yeah, so even back in 2007 when the debugger support was admittedly much weaker than it is now, there was this controversy. People thought that good programmers don't use debuggers. And there was a series of blog articles written back and forth defending one side or the other. I'm here to tell you I do not support the idea that good programmers don't use debuggers. However, I myself don't use it often. I have a layer of things that I do when I'm debugging programs or debuggers. Not the first thing I reach for, but it's certainly in my bag of tools that if I need it, I can reach for it. We're going to talk a little bit about that bag of tools and how you might use it. Okay, so I already did the survey who made how many people here. How many people are of the opinion that you shouldn't be using a debugger? Is there anybody in here? Let's see. I guess it's only radical blog writers that hold that opinion. Okay, well, that's awesome. That's awesome. And truthfully, those of you that do use the debugger probably are a lot more expert at it than I am. That's why I'm kind of backing off of my title, Mastering the Review Debugger. But I'm going to show you a few tricks. And if you've never used it before, it'll make it really easy to use. Cool. Let's start with a demo. I'd give a talk called Presentations for Presenters. And in that talk, I tell them the scariest thing that you can do is a live demo. So here I am. Okay, let's look at a simple program I'm calling Convert. And here it is in all its glory. It's got it's more much more complicated. It needs to be just so I got a little something to debug here. You see it's not got degrees converter converts from degrees Fahrenheit to degrees Celsius. You initialize it with the degrees Fahrenheit. There's a degree C that calculates how to convert that number. And then in the main program down here where the cursor is down here, we create a converter, grabbing the argument from the argument list, and then we print out the converted value. So let's run that and see how that works. We convert 98.6. So I happen to know that actually works out to be an even number in Celsius. Oh, yeah, that's really even. I have a bug in my program. Well, what's the first? Let me ask you, when you discover a bug like this, and and what's the first tool that you use to investigate it? My eyes. My eyes. Your eyes. Okay, very good. I'm waiting for a particular answer that no one said yet. Oh, thank you. Thank you. Yes, run your tests. I think that's one of the big reasons that the bugger is not needed as much because when you're developing in a TDD style, you write a little bit of code, you run your tests, write some tests, you write some code, you write some tests, you write some code. So when you get a bug, your tests immediately tell you what the bug is. And the fact that you just wrote a little bit of code is a good indicator of where to start looking for that bug. So you don't have to dig deep to find out where the bug is. So let's I don't have tests for this thing. I'm just running from the command line. But I do notice it's wrong. So let's jump into that. And I want to know what's going on. So right here, let's make sure we're getting the right result out. And my first tool that I reach for is the Ruby put statement. How many people use puts a lot? That is perfectly fine. Because for a lot of things, for shower debugging is a perfectly good thing. In fact, I use it so much that my editor has a macro for doing that. Okay, and I always I always use that debug colon thing and all these debug statements so I can rep them and remove them after the fact. Because I don't want to leave them littering the code. So let's run it now. And I say the result is that didn't help me very much. Okay, what else can we look at? Well, there's a there's an offset in there. So let's put the offset in there. And offset 32. Okay, that looks good. Well, there's a factor. Let's let's look at the factor. And the factor is zero, which is kind of an indication that that's where the problem lies. So we go back now we use our eyes actually probably shouldn't use our eyes to begin with. But sometimes we just kind of jump in. So we use our eyes and we look and see how factor is calculated here. We see I'm doing an energy divide. Yeah, that we have to divide floating point numbers if we want a floating point results. So we fix that. And bam, we've got 37 as our output. So that's good. Because you know what I did though? I had to use puts and I wasn't sure where the error is. So I had to kind of probe around a little bit. I tried looking at result I looked at this and look at a couple things before I found the thing where the problem resided. That's kind of typical with puts. If you don't know where the problem is, you're kind of probing with puts, you got to run it several times. Now if you got unit test set up, and you can rerun a unit test over and over and over again, that's not too bad. But but sometimes you want something a little more interactive. Let me show you a little trick here. Let's take out all these put statements and instead, I'm going to use a library called pride. How many people have used pride? Awesome. Yeah, pride is really interesting. So binding pride, let's put that right there. And I'm going to switch to a real terminal here. Yeah, I'm in the right place. I'm going to Ruby require pride because I have to require the library here. And let's run convert 98.6. And that dumps us into an interactive IRB session. Essentially, it's kind of like an enhanced IRB session, where we can see what the bindings are. And and everything. And you can do things in here. So you can do normal things like I can ask for what is the factor. And I remove my box, we're not seeing the bug right now, but I can explore the variables. I can get a list of all the things available to me. You can see here in the list, it gives out a bunch of things with underscores under that. But it also gives out this reduce the sizes to we've been there, you can see here, we have degrees f listed, print out the degrees that I can explore the object and look at its instance variables, I can look at all its bindings and I can do other things as well. Prime has a complete list of shell commands that you can actually run shell stuff from within it. There's an LS, here's an LS command on the containing directory. So you can do a lots of interesting things within pry. You can delve into objects. Let's I find the command syntax for pride really, really interesting, because it's all kind of command line base. So when I see the within pride, I'm not changing directories. In the in the operating system sense, I'm changing the local viewpoint of where pride is looking at. So I can see the down into objects. The only objects of interest we have right now is maybe degrees f. So let's see the end of that. And we also there's not too much in degree, you know, what kind of object is degrees f? It's a fully point number. We are inside a fully point number. Was that pride? Is that cool? A little weird. Okay, to get out of an object, you can see the up. Okay, and now we're back at the outer edge of it, we can see the up again. And that takes us out of the entire program. So you can move around, you look at objects, you can examine them. If you are not quite sure where the problem lies in your data. But you know that right here at this point in the code, something needs to be right and you want to explore the data in your system at your point in your code, pride is an excellent tool to do that. You can really walk object trees and move around and look at things. Okay. Questions or pride? Yeah. No, you cannot step. Pride is a data explorer. It is not a program stage for which we'll get to in just a minute. Yes. I'm working on j ruby. Oh, that's a good question. Do you know if it works on j ruby? No idea. Yeah, I think I, if I remember right, I remember reading on the document page that they're working on getting it on j ruby. And I think that's a little old. So I think it's working on j ruby, but I'm not sure. I know there's some issues. Imagine that. Uncle Bob was talking about diversity here and he says, what's the major feature that's common across here? I was thinking MacBooks. So if you're looking for diversity, there is a group of programmers out there that really, really needs some good ruby love. So if you are interested in helping the windows developers, more power to you. So I don't have to. No, seriously, that is that is a good thing to do. Okay, so I have a question for pride. Pride is awesome. If you're not using try now, put it do a gem install pry and just start putting it in your debugging sessions. Yeah. Okay. Okay, well, that's an interesting thing. I don't know. Let's let's, we'll try that in the next demo, because that's an interesting question. Okay, the question is, can I get into pride from a regular debugging session? I imagine you can, but we'll give it a try and see. It might get confused about where the source is, but most will see once. Okay. Next, we'll talk about a little program, I want to explain the program a little bit before we jump into it. This is the Gilded Rose Cata, which is essentially a refactoring Cata. We're going to see it before the refactoring is done. So the code is going to be ugly, which is good because I'm demonstrating a debugger, which is exactly what I want. So Gilded Rose is essentially an inventory program. You have a list of items, and you track two things on these items, the quality of the item, how much it is worth, and how many days you have to sell it in. So under normal conditions, a normal item, when you update it on a daily basis, the quality should go down by one tick. And the selling date, the number of days you have left to sell it has to go down by one day. However, if you're longer after the sell date, the quality goes down by two rather than one. And that's for normal items, but you have special items like age three, where the older it gets, the higher the quality. So the quality goes up for age three items. And when you get the sell date, it goes up by two, so it gets even better. You have strange items like the Sulfurus, the Hand of Ragnaros. How many people even know what that is? Okay, you're wild players. The Hand of Ragnaros is an epic item, and its quality does not change, and its selling date does not change. It is a fixed value, no matter what time it is. Okay, the guy who put this cotton together is obviously a World Warcraft fan here. We've got some other references here. Here we have a backstage pass. Its quality goes up the closer you get to the concert date, the more valuable the backstage pass is going to be. In fact, when you hit 10 days within the conference, it starts going up by two. And when you hit five days before the concert, the quality starts going up by three. However, after the concert, quality drops to zero immediately. Not worth it saying after the concert. So we've got a bunch of different items, all with different business rules of how the quality and the selling date change over time. And the Gilded Rose application takes a list of these items and walks them through all these various scenarios and make sure and there's some unit tests set up. Yay unit tests are set up to make sure that everything works. Okay, so let's demo the Gilded Rose. So I've opened up the spec for the Gilded roses are written with given when then our spec given. So given an instance initial sell date initial quality and given an item with those values set in when you update the item under these circumstances, then the quality should decrease by one the sell and date should decrease by one. That's essentially what you saw in the slide just kind of captured in our spec language. So let's run these tests. Oh, we've got failures. We have four failures here. And gosh, I don't know about this. Let's look at the code. Goodness. What is this mess? I did mention this is a refactoring. So it's your goal in normal circumstances is your goal to to rewrite this code into something more maintainable. In fact, this is a great thing because because the kind of says, okay, you have a new rule to add added to this set of if pass. Okay. But obviously, the original is not working right now. So let's let's use our normal technique here. So, so we get a list of items update quality on items. We walk through each item. So here seems to be a good place to drop in our pride test, right? So let's we'll just require pride call binding on it right away. We'll do that. And we'll go over here. And let's see, wait, hang on, I want to go back to the Joe says that when he watches me do live coding, it's like my fingers suddenly forget how to type. And I'm experiencing it just a little bit. We see a failure right here online 116. Oops, 116. Okay, so it's this test right there. So let's just run that spec. I'm going to do that from the command line like this, our spec, gilded, I'm in the right directory, our spec, gilded rose dot rb. No, there's our spec, rb. And let's just run the test online 116. We're going to run one test. That way you don't get lots of things going through this. Okay, great, we're in pride. Let's let's take a look. Let's take a look at our item, item. It's a backstage pass. Yeah, we knew that. It's got a selling date of 10 and a quality of 10. If you can read that there, okay. That all looks good. Now what do I do? What we're faced with here is a problem not in data, but in the logic of our code. And for this pry is pretty much unhelpful. We want to step through the logic of this code and see what it's doing, rather than to examine the state of the data afterwards and see what went wrong. So this is a pure case where pry, although very handy for exploring data, doesn't help us at all. So let's use a different technique. Get out of pride. Let's go back to here. And let's instead of saying pride, let's say debugger. This is how you invoke the debugger in Ruby. It's simply like that. And then when I run it, here's our spec. I say dash dash debug on the command line that will cause our spec to load the debugger for me. Then when I run it, bam, now I'm in the debugger. Let's do a little something here. Let's say set auto list. Is it true? Does that how you do it? Expecting a one or a one. So auto list on that's better. Okay. I can ask the debugger where I'm m and I can tell I'm right here on this if statement. If the item is not hb and the item is not a back stage pass. Okay, good. Let's walk through the code. The command you want to use in the debugger is n. So we'll do n. Since I turn auto list on, it's going to constantly tell me where I'm at. I can see now I skip down to if the item quality is less than 50. Well, we know it's 10. We can look at the item. The e command evaluates Ruby expressions in the debugger. So I can ask for the item. And it tells me okay, there it is for this particular concert. The salendate and the quality is 10. So that's so we should pass this test and go to lines line 12. Okay, so I hit n again. And online 12 good. The next one should take us to line 13. Line 13 is the test to see if it's a backstage pass. It is a backstage pass. So I should go to line 11. Let's hit and notice I'm just hitting return now it remembers the last command I entered. So we'll just repeat that if I just hit return. That's really handy for walking through things. And oh, I did not go to line 14. I jumped down to line 27. Let's list line 14 again, our line 13. I don't just backstage passes to a TFK. Do you know what that stands for? That's the artist formerly known as level 80 elite torrent chief, another warcraft reference. I'm gonna leave you warcraft songs or rock band that does that. Okay, cool. So alright, so oh, look, let's let's look at our item. Is it name? Oh, looking here, the item name is level 80 with a zero. This is level 80 with a capital O. I mistyped the code and I've got a typo in my code. Now here, the problems in the code is not the data. I can look at the data all day long with pride and never seen this issue. So the debugger is perfect for finding logic errors in your code base. Okay, that's it must jump back to the running. I just got a few minutes left. So let's just run through some debugger stuff really fast. Like I say, they're not going to master it. But if you know a handful of commands, you get a lot done in the debugger, you valuable evaluate Ruby expressions. So someone asked, Can you jump into pride? Chances are, this is good enough, you don't really need pride does something at least allows you to look around inside of Ruby. The next command we saw steps you through the logic. The ask command also steps you to the logic steps into methods as they're called. So if you want to delve down into a method, rather than just walking over it as it executes the S command is for that. There's various list commands in the set auto list command is obviously one that you want to be using to in this mode. You can set breakpoints like this, you can delete breakpoints breakpoints allow you to run until you get that spot the code and then it stops and drops into the debugger. You can display expression. So say, give me the this Ruby expression right here. And every time I step, tell me what value it so you can watch the data change as you're stepping through the code. That's real handy for that. You're not can't figure out where something is changing. And of course, there's exit. There's a help command, or all this information came from. So if you ever lost his type help, and you can ask for help for individual commands, it's pretty straightforward. It's easy to use. If you're in one nine, you need to install the Ruby debugger one nine version of it. It's a gem here in Ruby one eight. Just this just the Ruby debug normal gem. So both work and both work fairly well. And I've probably got one minute left for questions. We didn't get a chance to see if probably worked or not. But I'll check that out there. words. Yeah. Okay, cool. Because we started early. Okay, awesome. Awesome. The guy here with the iPad keeps flashing me one minute left. So I was going, he's at 49 seconds. We're gonna stretch that out if you have if you have more questions. So we're running, we're running ahead of time. He gave me two minutes and 40 seconds now. Okay. All right. Yes, in the back. Yes, there is an IRB command in the debugger that you can just drop into regular IRB and do all your regular IRB stuff. So the problem with the debugger is that every time you want to evaluate something, you have to type e something which is a little annoying. But you can drop into IRB and then you got all the regular IRB things and get out of IRB and go back to the debugger. And I think there's even an auto evaluate mode, which I think does if it can't recognize it as a command, it goes and figures Oh, this is a Ruby expression. Let's evaluate it anyways. Okay, you can. Okay, the comment is there's, there's a mode you put it where it always prints out the object, like IRB. And you can also in your debugger or C file, you can set up so automatically goes in that mode for you. When you get into the debugger, so you don't have to set it up automatically. I imagine putting this up, auto list, and there would be a useful thing to there are certain editors, I know Emax, if you set it up just exactly right, you max will split your source code into the top window, and the debugger interaction pane in the bottom window, and you actually watch your code execute within an Emax editor buffer. So that's, and other editors do that as well, I imagine some of the nicer IDEs allow nice integrations of Ruby debugger, you can run the debugger within a Rails program that is quite easily doable. I have done that and that's really handy to do as well. Yes, the question is, have I ever had the debugger open in a different context or scope, and where the debugger line is, I've never had that situation? Assuming you have, you know what causes that? Oh, it's the end of the method, sometimes you pop the stack before it gets called, interesting. Okay, just do like semi-college. You can't actually, this is cool, you can actually get a backtrace of everything you've been in the code, everywhere you've been in the code, all the call stacks down, and you actually walk up and down that call stack and print out variables at different levels of the call stack as well. So you say, I'm in this thing, I'm being passed this value, how did this value get to be this? You can walk up the stack to the point that value was defined and print out the environment of that method up there. So that is a really useful thing to do. The debugger is a super x-ray machine into your black box. It lets you explore all kinds of things. Now, you don't need it a lot. As I say, I don't run the debugger all the time. My first tool is puts, my second tool is pry, but if I get into a place where I need it, debugger is a good tool to, run at least once, get a handle on a few of these commands and I think they'll be doing good. Okay, how much time do I have? You've still got more time. So more questions? Yes. So in Java, you can connect to a running JVM through TCP with the debugger? How do you do that with Ruby? You can do that with Ruby. I have not done it, so I can't give you some practical advice on that, but there are commands. If you look at the debugger, help things that are telling you how to do that. Thanks. Okay. You might have to invoke the Ruby process in a special mode to make that available. But yeah. How to do what? Invoke the debugger on a running process, which is particularly useful if you're debugging some kind of long running server thing that you can't run. I generally like to use the debugger in my unit test because I can get in, I can run the thing over and over. I know exactly what is set up in the unit test. So I find that helpful there to debug from that point. Yes. I kind of trailed off from using it because of spork, spork for my test. Okay. Also running how as the server on my map. Okay. And do you have any experience getting around either of those? I don't run spork. I try to get my unit test to run fast enough without that. And I'm gonna definitely look into some things I'm gonna bother. So last night, particularly Corey Haines, who does this all the time, I've had Corey Haines that some techniques for getting your rails test from really fast by not loading rails all the time when you need them. So if you need fast tests, I tend to go that route rather than running a lot of infrastructure stuff to make to just throw more power at it. Yeah. If you're running spork, you should not be debugging as a comment. Okay, fair enough. Fair enough. And I imagine even you're using spork should be easy enough because when you're debugging, you want to run one unit test, don't run the whole suite. So there's no need to run spork for those. Alright. For once, going twice. I have stickers taught to me later if you need anything. Thank you very much.