1 00:00:17,800 --> 00:00:21,970 JOEL TURNBULL: Thanks for coming. 2 00:00:21,970 --> 00:00:23,730 My name is Joel Turnbull. 3 00:00:23,730 --> 00:00:26,399 I'm a developer for Gaslight in Cincinnatti, Ohio. 4 00:00:26,399 --> 00:00:30,449 I also head up and coordinate a blog over there, 5 00:00:30,449 --> 00:00:33,410 in case anybody ever wants to talk about that. 6 00:00:33,410 --> 00:00:36,769 But today, I'm here to talk about debugger driven 7 00:00:36,769 --> 00:00:43,769 development with Pry. Most Rubyists I know don't use 8 00:00:44,320 --> 00:00:51,280 debuggers. Rubyists I know, when faced with a problem, 9 00:00:51,280 --> 00:00:56,550 would prefer to ponder code than pop open a 10 00:00:56,550 --> 00:00:59,440 debugger and poke around. 11 00:00:59,440 --> 00:01:02,510 This is crazy to me. I've always thought it 12 00:01:02,510 --> 00:01:05,880 was, because to me, trying to solve a problem 13 00:01:05,880 --> 00:01:09,670 by pondering code is like trying to find your 14 00:01:09,670 --> 00:01:13,920 keys in the dark, when you're holding a flashlight, 15 00:01:13,920 --> 00:01:19,770 but you're consciously deciding not to use it. 16 00:01:19,770 --> 00:01:22,190 So why is this? I, I used to think 17 00:01:22,190 --> 00:01:24,560 it might be about egos or culture or something 18 00:01:24,560 --> 00:01:28,130 like that, but really it's pretty simple. I think 19 00:01:28,130 --> 00:01:30,420 we've had a lack of really good tools up 20 00:01:30,420 --> 00:01:36,690 to this point. But ultimately, my talk isn't about 21 00:01:36,690 --> 00:01:40,739 using debuggers in a traditional sense to fix software, 22 00:01:40,739 --> 00:01:44,250 but using debuggers as a tool in your workflow 23 00:01:44,250 --> 00:01:47,090 to build software. 24 00:01:47,090 --> 00:01:51,000 And, so why do I think we can do 25 00:01:51,000 --> 00:01:55,440 this right now? I feel like we finally have 26 00:01:55,440 --> 00:01:59,929 a tool that we can use to explore this 27 00:01:59,929 --> 00:02:06,489 debugger driven, debugger driven workflow. And that tool is 28 00:02:06,489 --> 00:02:06,860 Pry. 29 00:02:06,860 --> 00:02:09,190 Can I get a show of hands of who 30 00:02:09,190 --> 00:02:16,190 uses Pry? Awesome. Like, everybody. All right. Cool. So 31 00:02:16,970 --> 00:02:21,489 I'm talking about debugger driven development with Pry. Conrad 32 00:02:21,489 --> 00:02:23,920 Erwin gave a talk not even like six months 33 00:02:23,920 --> 00:02:26,880 ago called REPL Driven Development with Pry. I swear 34 00:02:26,880 --> 00:02:28,850 to god I had no idea. 35 00:02:28,850 --> 00:02:35,850 But, and both are accurate, I think. You know, 36 00:02:36,840 --> 00:02:39,560 but I think both terms kind of undersell what 37 00:02:39,560 --> 00:02:42,140 the power of Pry is. So here's my favorite 38 00:02:42,140 --> 00:02:47,100 definition. Pry is an IRB alternative and runtime developer 39 00:02:47,100 --> 00:02:49,660 console. So if we take the first part of 40 00:02:49,660 --> 00:02:53,610 that and we think about Pry as an IRB 41 00:02:53,610 --> 00:02:57,990 alternative, you know, anything that you can do with, 42 00:02:57,990 --> 00:03:02,930 with, both, both are REPLs, right. And, and a 43 00:03:02,930 --> 00:03:05,460 debugger is a REPL, too. Anything you can do 44 00:03:05,460 --> 00:03:08,350 in Ruby, you can do in IRB. Anything you 45 00:03:08,350 --> 00:03:11,900 can do in IRB, you can do in Pry. 46 00:03:11,900 --> 00:03:15,290 What makes both of them powerful, is they both 47 00:03:15,290 --> 00:03:20,620 leverage this idea of runtime. And, to me, runtime 48 00:03:20,620 --> 00:03:24,440 is all about immersion. It's about being immersed in 49 00:03:24,440 --> 00:03:28,590 a live system, where you can play with code 50 00:03:28,590 --> 00:03:30,580 and you can look at your objects and, and 51 00:03:30,580 --> 00:03:33,920 all that kind of thing. You can validate your 52 00:03:33,920 --> 00:03:40,920 implementations. Everything you need to do. And it's like, 53 00:03:42,290 --> 00:03:45,020 looking for your keys with a flashlight. 54 00:03:45,020 --> 00:03:49,140 So, given that Pry and IRB are both REPLs 55 00:03:49,140 --> 00:03:51,099 and they both have this idea of runtime, why 56 00:03:51,099 --> 00:03:56,520 should you use Pry instead of IRB? It's got 57 00:03:56,520 --> 00:03:59,280 a couple vital workflow features right out of the 58 00:03:59,280 --> 00:04:03,750 box. Syntax highlighting and tab completion. Both super handy. 59 00:04:03,750 --> 00:04:06,620 But, what I want to talk about today is 60 00:04:06,620 --> 00:04:11,489 some of the bigger, game-changing features of Pry. The 61 00:04:11,489 --> 00:04:18,488 first one is enhanced introspection. Here's our friend again. 62 00:04:19,220 --> 00:04:21,849 Introspection is the ability to, of, of a language, 63 00:04:21,849 --> 00:04:25,210 where you can ask a language questions about itself. 64 00:04:25,210 --> 00:04:29,250 And it's built into Ruby, and that's awesome. 65 00:04:29,250 --> 00:04:31,970 If you've ever asked a class what method you 66 00:04:31,970 --> 00:04:34,680 can call on it, or you've asked an instance 67 00:04:34,680 --> 00:04:41,449 what class it is, you're doing introspection. 68 00:04:41,449 --> 00:04:42,939 What if you want to go deeper? Like, what 69 00:04:42,939 --> 00:04:44,860 if you want to know what the class methods 70 00:04:44,860 --> 00:04:47,379 are versus the instance methods? You know, what if 71 00:04:47,379 --> 00:04:50,860 you want to know what methods are inherited, and 72 00:04:50,860 --> 00:04:52,610 from where? What if you want to know what 73 00:04:52,610 --> 00:04:58,099 state an instance holds onto during its life cycle? 74 00:04:58,099 --> 00:05:00,849 You can answer all these questions with plain Ruby 75 00:05:00,849 --> 00:05:05,289 and IRB. But the problem is, is that, it's, 76 00:05:05,289 --> 00:05:09,059 the, the amount of effort involved is non-trivial. I 77 00:05:09,059 --> 00:05:14,499 would classify it as daunting. 78 00:05:14,499 --> 00:05:21,499 So. Given that. You know. I would, I would 79 00:05:29,050 --> 00:05:35,400 classify this as DRTFM. This is what I, this 80 00:05:35,400 --> 00:05:40,710 is what I point to. I mean, this is 81 00:05:40,710 --> 00:05:44,289 the workflow that I like. 82 00:05:44,289 --> 00:05:46,939 I like to take the things out of the 83 00:05:46,939 --> 00:05:48,539 box. I like to get a feel for what 84 00:05:48,539 --> 00:05:51,819 the pieces are. I like to play around with 85 00:05:51,819 --> 00:05:54,300 them. I like to try to put it together 86 00:05:54,300 --> 00:05:56,889 without reading the manual, and if I get stuck, 87 00:05:56,889 --> 00:06:01,089 then I read the manual, right. 88 00:06:01,089 --> 00:06:06,229 The second really game-changing feature of Pry, to me, 89 00:06:06,229 --> 00:06:10,439 is extendability through plugins. And the best way that 90 00:06:10,439 --> 00:06:13,509 I can show this is to just demo some 91 00:06:13,509 --> 00:06:18,139 of my favorites for you. 92 00:06:18,139 --> 00:06:24,080 So, I'm gonna show you a Rails app. Instead 93 00:06:24,080 --> 00:06:27,699 of calling it in a normal way, like rails 94 00:06:27,699 --> 00:06:31,740 s, I'm gonna call it like this. Under the 95 00:06:31,740 --> 00:06:34,550 umbrella of Pry rescue. And I'll show you why 96 00:06:34,550 --> 00:06:40,330 in a minute. 97 00:06:40,330 --> 00:06:43,449 But here we are. This is an app I've 98 00:06:43,449 --> 00:06:46,300 been working on late, late nights, you know. Please 99 00:06:46,300 --> 00:06:50,400 don't steal this. This is a bowling score count, 100 00:06:50,400 --> 00:06:53,409 tracker, right. You can push any number after you 101 00:06:53,409 --> 00:06:56,289 bowl and it will record what you, what, how 102 00:06:56,289 --> 00:06:59,029 many pins you knocked down, right. 103 00:06:59,029 --> 00:07:01,430 So, the first thing I'm gonna show you about 104 00:07:01,430 --> 00:07:08,430 Pry, for those who aren't necessarily familiar, is how 105 00:07:09,969 --> 00:07:15,319 you invoke a runtime at any point in your 106 00:07:15,319 --> 00:07:18,520 application, where you're running Ruby, right. 107 00:07:18,520 --> 00:07:22,050 Here, I've inserted a couple binding dot prys. One 108 00:07:22,050 --> 00:07:24,999 into my controller action and one into my template. 109 00:07:24,999 --> 00:07:28,029 On the lower left we have our model. OK, 110 00:07:28,029 --> 00:07:32,069 so let's rerun it with that in mind. 111 00:07:32,069 --> 00:07:34,360 Let's go back to our running server, and we'll 112 00:07:34,360 --> 00:07:38,180 see that we've halted our execution here, and we've 113 00:07:38,180 --> 00:07:40,520 been dropped into a run time. And we can 114 00:07:40,520 --> 00:07:45,710 do things in here like look around. We can 115 00:07:45,710 --> 00:07:48,259 play lines of code. Let's play the line that 116 00:07:48,259 --> 00:07:52,219 sets the bowling game. And then we can look 117 00:07:52,219 --> 00:07:54,819 again. 118 00:07:54,819 --> 00:07:57,139 When we exit from this, we've returned from our 119 00:07:57,139 --> 00:08:00,149 controller. We're starting to render our template, and we've 120 00:08:00,149 --> 00:08:02,490 hit our next binding dot pry. You can put 121 00:08:02,490 --> 00:08:07,149 binding dot prys inside your erb tags, right. 122 00:08:07,149 --> 00:08:10,110 Same drill. We can look at bowling games. We 123 00:08:10,110 --> 00:08:17,110 can, we can step into our next, our, our, 124 00:08:18,360 --> 00:08:21,020 our implementations of our methods. Here we've stepped into 125 00:08:21,020 --> 00:08:24,860 the frames method of our bowling game model. 126 00:08:24,860 --> 00:08:29,499 Same drill. We can look around here. We can 127 00:08:29,499 --> 00:08:33,979 look at ourself. We can go to the next, 128 00:08:33,979 --> 00:08:38,690 or we can continue. 129 00:08:38,690 --> 00:08:43,779 So, you can see how handy that would be 130 00:08:43,779 --> 00:08:48,649 if things aren't necessarily blowing up, but, you know, 131 00:08:48,649 --> 00:08:55,649 something's not quite right, either. So what if things 132 00:08:56,940 --> 00:09:00,709 do blow up, though? Right. 133 00:09:00,709 --> 00:09:04,540 So, here I am. I'm gonna, I'm gonna spark 134 00:09:04,540 --> 00:09:07,940 an exception here by bullet, trying to bowl the 135 00:09:07,940 --> 00:09:11,269 next ball of my next frame. I'm gonna bowl 136 00:09:11,269 --> 00:09:14,910 a big nine. I'm gonna come back here and 137 00:09:14,910 --> 00:09:18,750 we've been dropped into a runtime, because an exception 138 00:09:18,750 --> 00:09:22,240 was thrown. That's what being under the watchful eye 139 00:09:22,240 --> 00:09:25,120 of Pry rescue is gonna do for us within 140 00:09:25,120 --> 00:09:27,730 this context here. 141 00:09:27,730 --> 00:09:33,230 So, some interesting, interesting things we can do here. 142 00:09:33,230 --> 00:09:36,089 We can call the show-stack command of the Pry 143 00:09:36,089 --> 00:09:40,540 stack explorer plugin. And we're seeing the whole stack 144 00:09:40,540 --> 00:09:44,880 here. this is like caller, but it's alive, right. 145 00:09:44,880 --> 00:09:49,259 We can move up the stack. We can move 146 00:09:49,259 --> 00:09:52,130 up the stack nine frames. We can move down 147 00:09:52,130 --> 00:09:54,380 the stack. We can take a look at the 148 00:09:54,380 --> 00:09:58,540 state of any object here at any level of 149 00:09:58,540 --> 00:10:00,470 our stack trace. 150 00:10:00,470 --> 00:10:02,060 We can look at our stack again just to 151 00:10:02,060 --> 00:10:05,360 see where we're at. We're on frame ten. But 152 00:10:05,360 --> 00:10:07,610 this is a big hairy kind of Rails stack 153 00:10:07,610 --> 00:10:09,019 trace, and we're not getting a whole lot of 154 00:10:09,019 --> 00:10:11,310 value out of that right now. 155 00:10:11,310 --> 00:10:15,440 So let's call the cd-cause command of Pry rescue. 156 00:10:15,440 --> 00:10:18,769 And see if it can track down what caused 157 00:10:18,769 --> 00:10:23,269 this problem in the first place. 158 00:10:23,269 --> 00:10:25,399 There we go. This looks more familiar, right. Here 159 00:10:25,399 --> 00:10:28,990 we are in our template. And I will guess 160 00:10:28,990 --> 00:10:32,040 that on line thirteen we have a problem with 161 00:10:32,040 --> 00:10:35,449 frame one. And that's true. So we just need 162 00:10:35,449 --> 00:10:36,709 to add a little bit of a guard in 163 00:10:36,709 --> 00:10:40,399 here, and say, you know, if we have pins 164 00:10:40,399 --> 00:10:44,050 on frame one, let's render that. Otherwise let's just 165 00:10:44,050 --> 00:10:46,259 render a dash. 166 00:10:46,259 --> 00:10:48,959 And we get feedback that that's going, that's what's 167 00:10:48,959 --> 00:10:52,019 gonna happen, right. We know that this is a 168 00:10:52,019 --> 00:10:54,199 working implementation. 169 00:10:54,199 --> 00:10:57,379 So let's copy our history. This is another plugin 170 00:10:57,379 --> 00:11:01,720 called Pry clipboard. That's gonna copy that implementation into 171 00:11:01,720 --> 00:11:06,470 my clipboard. I'm gonna edit a file where the 172 00:11:06,470 --> 00:11:10,529 last exception was raised. It drops me right where 173 00:11:10,529 --> 00:11:13,220 I need to be. I'm gonna paste in that 174 00:11:13,220 --> 00:11:20,220 implementation, drop back in, and I'm gonna ask Pry 175 00:11:23,180 --> 00:11:24,569 rescue to try it again. 176 00:11:24,569 --> 00:11:31,569 And we're back. And we've got our dash. So, 177 00:11:31,620 --> 00:11:35,899 and we can continue to bowl, right. That's legit, 178 00:11:35,899 --> 00:11:42,899 right. A five and a six. OK, cool. 179 00:11:44,670 --> 00:11:51,480 So, what do we do here? We used binding 180 00:11:51,480 --> 00:11:54,480 dot pry to invoke a runtime anywhere in our 181 00:11:54,480 --> 00:11:58,290 app where we're doing Ruby code. We used the 182 00:11:58,290 --> 00:12:02,810 pry-debugger gem to give us our step, next, and 183 00:12:02,810 --> 00:12:05,699 continue functionality that we expect out of our debugging 184 00:12:05,699 --> 00:12:09,379 tools. We used pry-rescue and ran our Rails app 185 00:12:09,379 --> 00:12:11,879 under the umbrella of pry-rescue to drop us into 186 00:12:11,879 --> 00:12:13,920 a runtime when things go wrong, so that we 187 00:12:13,920 --> 00:12:17,750 can poke around. We used the pry-stack_explorer gem to 188 00:12:17,750 --> 00:12:22,170 navigate the stack and explore state at any level. 189 00:12:22,170 --> 00:12:27,110 A few commands we saw were cd-cause in pry-rescue 190 00:12:27,110 --> 00:12:30,269 that took us to the, the root of our 191 00:12:30,269 --> 00:12:36,870 problem. We used play and we used copy-history to 192 00:12:36,870 --> 00:12:40,680 not mess around with, you know, copying things with 193 00:12:40,680 --> 00:12:44,029 our mouse and pasting them into our REPL, which 194 00:12:44,029 --> 00:12:47,060 can be a pain. We used the edit command 195 00:12:47,060 --> 00:12:49,149 with the e flag to take us to the 196 00:12:49,149 --> 00:12:51,379 file where the exception occurred so that we could 197 00:12:51,379 --> 00:12:56,930 fix it. And then we used pry-rescue, try-again, which 198 00:12:56,930 --> 00:13:01,850 under this, under the context of Rails, just replayed 199 00:13:01,850 --> 00:13:04,600 our request. We didn't have to reload our, our 200 00:13:04,600 --> 00:13:08,370 page, or do any of that nonsense. Reload the 201 00:13:08,370 --> 00:13:11,540 whole environment or anything like that, right. So it 202 00:13:11,540 --> 00:13:13,279 was fast. 203 00:13:13,279 --> 00:13:18,560 So, the, that's, that's great, and having demoed Pry 204 00:13:18,560 --> 00:13:20,740 in a debugger context, you know, I can show 205 00:13:20,740 --> 00:13:24,069 some of those things. But, really, what I find 206 00:13:24,069 --> 00:13:27,160 interesting is this idea of Pry as a runtime 207 00:13:27,160 --> 00:13:30,839 developer console, right. 208 00:13:30,839 --> 00:13:34,589 So there's some really awspect- really awesome aspects of 209 00:13:34,589 --> 00:13:37,019 Ruby, right. It's introspective, which we've talked about a 210 00:13:37,019 --> 00:13:39,040 little bit and we'll talk about more. And it's 211 00:13:39,040 --> 00:13:41,629 a dynamic and it's reflective, which means, you know, 212 00:13:41,629 --> 00:13:43,000 we don't have to compile it and we can 213 00:13:43,000 --> 00:13:46,970 change things on the fly in its runtime. 214 00:13:46,970 --> 00:13:49,019 And I think we, we take advantage of these 215 00:13:49,019 --> 00:13:51,720 things, you know, a lot in the code that 216 00:13:51,720 --> 00:13:55,939 we write, whether we're doing metaprogramming or monkeypatching or, 217 00:13:55,939 --> 00:13:58,980 or anything like that. But we, we haven't really 218 00:13:58,980 --> 00:14:01,839 taken advantage of, of these things in the tools 219 00:14:01,839 --> 00:14:04,879 and in our workflow yet. 220 00:14:04,879 --> 00:14:08,899 So, when I talk about workflow and our problems 221 00:14:08,899 --> 00:14:12,029 with our workflow, I see big problems with the 222 00:14:12,029 --> 00:14:16,439 traditional workflow in, in Ruby development that I, that 223 00:14:16,439 --> 00:14:18,610 I see. Right, I mean. By that I mean 224 00:14:18,610 --> 00:14:21,180 we write some code in an editor. We save 225 00:14:21,180 --> 00:14:24,060 it. We hop over to a terminal or we 226 00:14:24,060 --> 00:14:26,389 pop over to a webpage and reload it and 227 00:14:26,389 --> 00:14:28,600 run it to see if it worked and, if 228 00:14:28,600 --> 00:14:31,079 it worked, we go back and continue on. If 229 00:14:31,079 --> 00:14:33,310 it didn't, we fix it, we save. We go 230 00:14:33,310 --> 00:14:38,860 back. We reload it, rerun it. Rinse, repeat, right? 231 00:14:38,860 --> 00:14:42,980 What, what are, what problems do I see with 232 00:14:42,980 --> 00:14:46,939 this? First of all, it's disruptive and it's distracting 233 00:14:46,939 --> 00:14:49,629 to keep switching back and forth, right. Some amount 234 00:14:49,629 --> 00:14:53,810 of context-switching is always gonna be imminent, right. But 235 00:14:53,810 --> 00:14:56,410 any effort you can make to reduce that is 236 00:14:56,410 --> 00:14:58,949 just gonna be a huge win for your flow, 237 00:14:58,949 --> 00:15:02,300 you know, and your focus. 238 00:15:02,300 --> 00:15:03,910 The second problem I see with that is it's 239 00:15:03,910 --> 00:15:06,060 just guess work. We just write some code. Oh, 240 00:15:06,060 --> 00:15:08,430 yeah, I think it's gonna work. We save it. 241 00:15:08,430 --> 00:15:10,519 We go over. We run it to see if 242 00:15:10,519 --> 00:15:13,009 it works. We're just taking shots in the dark, 243 00:15:13,009 --> 00:15:16,050 you know. You can ask this guy. 244 00:15:16,050 --> 00:15:19,910 Taking shots with a flashlight is much more accurate. 245 00:15:19,910 --> 00:15:23,339 And recommended, apparently. So do that. 246 00:15:23,339 --> 00:15:26,569 And, to me, it just seems backwards, right. We, 247 00:15:26,569 --> 00:15:31,300 we're like solidifying and codifying our code into our 248 00:15:31,300 --> 00:15:33,939 code base just in an attempt to see if 249 00:15:33,939 --> 00:15:37,579 it works. It should be the opposite. Our code 250 00:15:37,579 --> 00:15:42,459 base, it should be the, the record of code 251 00:15:42,459 --> 00:15:46,559 that we've, we've already validated, right. And I, I 252 00:15:46,559 --> 00:15:49,939 mean these things are just kind of things that 253 00:15:49,939 --> 00:15:52,970 we accept and, and we, we take for granted, 254 00:15:52,970 --> 00:15:53,410 right. 255 00:15:53,410 --> 00:15:57,040 But I mean, I think other languages have, have 256 00:15:57,040 --> 00:16:01,410 been more effective and intentional about integrating this idea 257 00:16:01,410 --> 00:16:06,050 of a runtime into the, their workflow, you know. 258 00:16:06,050 --> 00:16:09,689 And blurring this line between static and running code. 259 00:16:09,689 --> 00:16:11,949 Clojure comes to mind, right. 260 00:16:11,949 --> 00:16:14,759 But, we've talked about the awesome aspects of Ruby, 261 00:16:14,759 --> 00:16:17,809 and there's really nothing that restricts or limits us 262 00:16:17,809 --> 00:16:19,689 from doing the same, right. I mean, I think 263 00:16:19,689 --> 00:16:23,519 the Ruby language is, the Ruby language enables it, 264 00:16:23,519 --> 00:16:26,249 you know. It's just that up to this point, 265 00:16:26,249 --> 00:16:29,680 we really haven't had the tools to do so. 266 00:16:29,680 --> 00:16:33,939 So, we talked about these workflow problems. How does 267 00:16:33,939 --> 00:16:38,759 Pry solve these workflow problems, right? I see that, 268 00:16:38,759 --> 00:16:41,730 you know, the introspection and the documentation and the 269 00:16:41,730 --> 00:16:46,199 source code browsing, which we'll see in a minute, 270 00:16:46,199 --> 00:16:50,860 that's, that's baked into Pry, gives us ninety percent 271 00:16:50,860 --> 00:16:53,610 of the information that we need to write code 272 00:16:53,610 --> 00:16:57,529 right now, you know, in most cases. 273 00:16:57,529 --> 00:16:59,079 It has a runtime that you can throw your 274 00:16:59,079 --> 00:17:01,569 code against and validate it and get feedback on 275 00:17:01,569 --> 00:17:05,089 whether it, whether it works or not, immediately. And 276 00:17:05,089 --> 00:17:07,280 it's smart about editing. You don't have to think 277 00:17:07,280 --> 00:17:10,770 about what file you need to open. Pry usually 278 00:17:10,770 --> 00:17:13,449 knows what file you want to edit and usually 279 00:17:13,449 --> 00:17:15,800 knows exactly where you want to edit it. Which 280 00:17:15,800 --> 00:17:18,300 is really nice. 281 00:17:18,300 --> 00:17:25,300 So, when I talk about this idea of runtime 282 00:17:27,300 --> 00:17:32,050 development, I'm really talking about being immersed in this, 283 00:17:32,050 --> 00:17:36,510 in this environment that, you know, loves us and 284 00:17:36,510 --> 00:17:40,580 can give us feedback, and, and is alive, right. 285 00:17:40,580 --> 00:17:42,220 So we want to spend the majority of our 286 00:17:42,220 --> 00:17:45,560 development time there, and we want our editor to 287 00:17:45,560 --> 00:17:47,270 just be an after thought. And that's just a 288 00:17:47,270 --> 00:17:49,710 place where we just push working code when it's 289 00:17:49,710 --> 00:17:51,190 done, right. 290 00:17:51,190 --> 00:17:54,620 So, let me demo to you a little bit 291 00:17:54,620 --> 00:18:01,620 about how I see that working, right. 292 00:18:02,580 --> 00:18:08,040 So. Our mission is to write an empty class 293 00:18:08,040 --> 00:18:11,200 definition, OK. This is just a script. No Rails 294 00:18:11,200 --> 00:18:15,160 involved here or anything. But given a class like 295 00:18:15,160 --> 00:18:18,400 name like BowlingGame, we want to create a file, 296 00:18:18,400 --> 00:18:22,190 bowling_game dot rb, and write a class definition to 297 00:18:22,190 --> 00:18:26,590 it, like class BowlingGame empty space end. Right, and 298 00:18:26,590 --> 00:18:30,060 I've created a little skeleton here of, of how 299 00:18:30,060 --> 00:18:31,870 I think that might work, right. 300 00:18:31,870 --> 00:18:33,930 We're gonna, we're gonna read in a string from 301 00:18:33,930 --> 00:18:36,680 the command line, we're gonna pass that string into 302 00:18:36,680 --> 00:18:39,640 a method called file_name_for_class and get a file name. 303 00:18:39,640 --> 00:18:42,200 We're gonna pass that string into a method called 304 00:18:42,200 --> 00:18:45,800 class_definition for class and get a class definition, and 305 00:18:45,800 --> 00:18:48,070 then we're gonna create that class by writing that 306 00:18:48,070 --> 00:18:52,740 class definition to that file. Right. 307 00:18:52,740 --> 00:18:54,800 So let's step out here and let's just run 308 00:18:54,800 --> 00:18:58,320 that. So, we get an expected error, right. We 309 00:18:58,320 --> 00:19:02,570 haven't implemented anything called file_name_for_class, yet. So we could 310 00:19:02,570 --> 00:19:04,880 jump into our editor and start coding and all 311 00:19:04,880 --> 00:19:10,220 that, but why don't we see what this is 312 00:19:10,220 --> 00:19:13,130 like. 313 00:19:13,130 --> 00:19:16,770 Why don't we use Pry rescue and leverage that 314 00:19:16,770 --> 00:19:19,610 exception to drop us into a runtime and start 315 00:19:19,610 --> 00:19:25,570 this runtime development process. So we do that. We 316 00:19:25,570 --> 00:19:28,030 get the same error, but the difference is, we're 317 00:19:28,030 --> 00:19:32,920 inside of a runtime now, OK. So, the first 318 00:19:32,920 --> 00:19:35,200 problem is pretty easy. We know that we need 319 00:19:35,200 --> 00:19:41,380 to define file_name_for_class. And we do so, right. 320 00:19:41,380 --> 00:19:44,370 The difference is in here, I'm gonna raise, in 321 00:19:44,370 --> 00:19:47,760 the implementation of this class, and drop back out. 322 00:19:47,760 --> 00:19:50,240 And I'll show you why. When we ask Pry 323 00:19:50,240 --> 00:19:54,800 to try again, we get in here. We're right 324 00:19:54,800 --> 00:19:58,030 where we need to be to define the implementa- 325 00:19:58,030 --> 00:20:01,790 working implementation of this class. Although, I already know 326 00:20:01,790 --> 00:20:06,090 that I have forgotten to pass in the BowlingGame 327 00:20:06,090 --> 00:20:07,760 string, like I always do. 328 00:20:07,760 --> 00:20:12,340 OK. Now we have everything we need. So we 329 00:20:12,340 --> 00:20:15,130 have something like BowlingGame, right, and we're looking for 330 00:20:15,130 --> 00:20:20,770 something like bowling_game dot rb, OK. So I'm just 331 00:20:20,770 --> 00:20:24,970 gonna preview my favorite Pry command of all time 332 00:20:24,970 --> 00:20:28,080 here. ls. 333 00:20:28,080 --> 00:20:31,320 When I call ls, and give it the class 334 00:20:31,320 --> 00:20:34,520 or the object I'm working with, I immediately know 335 00:20:34,520 --> 00:20:37,400 I'm working with a string and I'm seeing all 336 00:20:37,400 --> 00:20:39,890 of the methods that are available to me on 337 00:20:39,890 --> 00:20:42,300 that string. And when I say all of the 338 00:20:42,300 --> 00:20:45,240 methods, I don't mean all of them. Notice that 339 00:20:45,240 --> 00:20:50,040 the object methods are not in here. And, you 340 00:20:50,040 --> 00:20:53,680 know that if you've ever used IRB to get 341 00:20:53,680 --> 00:20:56,680 the method, you always do, thing dot method minus 342 00:20:56,680 --> 00:20:59,660 object dot methods blah, blah, blah. 343 00:20:59,660 --> 00:21:02,440 The, that's just noise, right, in most cases. So 344 00:21:02,440 --> 00:21:06,530 the default is just to leave that out. The 345 00:21:06,530 --> 00:21:10,170 developers of Pry have thought of that, right. So 346 00:21:10,170 --> 00:21:15,570 we can try to class downcase, which gets us 347 00:21:15,570 --> 00:21:18,250 so close, but yet so far away. We don't 348 00:21:18,250 --> 00:21:20,820 really know where to put that underscore. 349 00:21:20,820 --> 00:21:26,360 But, as Ruby devs, Rails devs, we know we 350 00:21:26,360 --> 00:21:29,250 have things like ActiveSupport that can help us out 351 00:21:29,250 --> 00:21:34,570 with that. 352 00:21:34,570 --> 00:21:37,360 So we include that, and now when we ls 353 00:21:37,360 --> 00:21:39,980 our class, we've got some extra stuff in here, 354 00:21:39,980 --> 00:21:43,650 right. Demodulalize, deconstantize, right. That kind of stuff. And 355 00:21:43,650 --> 00:21:46,390 if it, that's hard to see, we can just 356 00:21:46,390 --> 00:21:51,400 ls ActiveSupport::Inflector itself and see what's available to us 357 00:21:51,400 --> 00:21:53,070 there, right. 358 00:21:53,070 --> 00:21:55,530 So we need an und, we needed an underscore. 359 00:21:55,530 --> 00:21:59,570 I see a method called underscore there. Tab completion 360 00:21:59,570 --> 00:22:02,450 is nice. All right. So now we're getting a 361 00:22:02,450 --> 00:22:05,930 lot closer. All we need to do is stick 362 00:22:05,930 --> 00:22:10,870 on our file exception, and I think we're done, 363 00:22:10,870 --> 00:22:11,780 right. 364 00:22:11,780 --> 00:22:16,350 So that, there's our filename. So let's copy that. 365 00:22:16,350 --> 00:22:22,750 Let's drop back into our file. Right here, exactly 366 00:22:22,750 --> 00:22:26,320 where we need to put the implementation, let's put 367 00:22:26,320 --> 00:22:30,100 it in there. And let's save it and continue 368 00:22:30,100 --> 00:22:32,810 on. OK, I know, I'm not gonna continue through 369 00:22:32,810 --> 00:22:37,140 this whole thing, in the interest of time, but 370 00:22:37,140 --> 00:22:42,150 I do want to, to implement this last method 371 00:22:42,150 --> 00:22:44,070 inside of the create_class, so I can talk a 372 00:22:44,070 --> 00:22:47,280 little bit more about what I love about introspection, 373 00:22:47,280 --> 00:22:48,750 right. 374 00:22:48,750 --> 00:22:50,800 Let's just reflect on what we did there, though, 375 00:22:50,800 --> 00:22:54,070 with the workflow, OK. So we used, the, we 376 00:22:54,070 --> 00:22:56,930 used pry-rescue to leverage the power, you know, to 377 00:22:56,930 --> 00:23:00,050 leverage that exception, to pop us into a runtime, 378 00:23:00,050 --> 00:23:03,300 and we used the runtime of the debugger not 379 00:23:03,300 --> 00:23:09,620 to fix code, but to drive our development process, 380 00:23:09,620 --> 00:23:12,020 right. 381 00:23:12,020 --> 00:23:17,030 So. We're in here. We've raised inside of our 382 00:23:17,030 --> 00:23:20,850 create_class method. We try again. We've got our file 383 00:23:20,850 --> 00:23:27,850 name, and we've got our class definition. And we 384 00:23:28,860 --> 00:23:32,380 have this file class, right. And, and I know 385 00:23:32,380 --> 00:23:34,450 about this file class, and I know this is 386 00:23:34,450 --> 00:23:36,990 exactly what I need to get the job done. 387 00:23:36,990 --> 00:23:39,090 But, I mean, this is exactly what I, what 388 00:23:39,090 --> 00:23:42,250 happened to me. I don't really remember exactly what 389 00:23:42,250 --> 00:23:44,370 I need to do here, OK. 390 00:23:44,370 --> 00:23:47,670 So I can pop out to StackOverflow or I 391 00:23:47,670 --> 00:23:50,780 can pop out to, to Ruby-docs or something and 392 00:23:50,780 --> 00:23:54,650 take a look. Or I can just ls file, 393 00:23:54,650 --> 00:24:01,020 right here. And just take a minute to look 394 00:24:01,020 --> 00:24:04,330 at this, and think about all of the low-level 395 00:24:04,330 --> 00:24:07,640 Ruby instrospection acrobatics you would have to go through 396 00:24:07,640 --> 00:24:11,930 to get this brain dump of information right here. 397 00:24:11,930 --> 00:24:13,940 We've got all of the methods that you can 398 00:24:13,940 --> 00:24:16,480 call on instances of file. We've got all the 399 00:24:16,480 --> 00:24:19,250 methods you can call on the file class. We've 400 00:24:19,250 --> 00:24:22,690 got all of the methods that file inherits, and, 401 00:24:22,690 --> 00:24:25,650 from its superclass, and we know what that superclass 402 00:24:25,650 --> 00:24:26,950 is. IO. 403 00:24:26,950 --> 00:24:29,070 We also know all the constants involved and if 404 00:24:29,070 --> 00:24:33,200 there was state involved in class or instance variables. 405 00:24:33,200 --> 00:24:37,870 We would see that here as well. So, all 406 00:24:37,870 --> 00:24:42,600 of a sudden, I'm informed about, about everything I 407 00:24:42,600 --> 00:24:45,270 need to know about this class, and I have 408 00:24:45,270 --> 00:24:47,770 a pretty good idea, just from a, from a 409 00:24:47,770 --> 00:24:50,750 moment's notice, of how I can use it, or 410 00:24:50,750 --> 00:24:54,380 what I can do to play around with it. 411 00:24:54,380 --> 00:24:59,730 So let's. I see the right method. And I 412 00:24:59,730 --> 00:25:02,390 don't really want to write anything or mess with 413 00:25:02,390 --> 00:25:04,990 anything right now, so I'm just gonna look at 414 00:25:04,990 --> 00:25:09,150 the documentation for it. OK. It opens the file. 415 00:25:09,150 --> 00:25:11,490 It optimally seeks to the given offset. Writes a 416 00:25:11,490 --> 00:25:14,690 string, then returns the length written. Write ensures that 417 00:25:14,690 --> 00:25:17,090 the files close before returning. This sounds like what 418 00:25:17,090 --> 00:25:18,320 I want. 419 00:25:18,320 --> 00:25:22,110 I page down. I see some examples there. Great. 420 00:25:22,110 --> 00:25:26,670 I'm ready to go. 421 00:25:26,670 --> 00:25:33,520 Alternatively, I can do the same and call show-source, 422 00:25:33,520 --> 00:25:36,190 OK. Which isn't doing a lot for me here, 423 00:25:36,190 --> 00:25:40,490 but when I'm in my, my own code base, 424 00:25:40,490 --> 00:25:43,450 this is what I lean on more often, right. 425 00:25:43,450 --> 00:25:50,410 So, let's get our bearings again. 426 00:25:50,410 --> 00:25:57,410 And let's give it a try, right. File.write(file_name.class_definition). OK. 427 00:26:02,190 --> 00:26:04,570 Something happened. It seemed to work, right. How do 428 00:26:04,570 --> 00:26:09,590 I know? Really easy to shell out in Pry. 429 00:26:09,590 --> 00:26:13,240 You get really nice output. Exactly what you would 430 00:26:13,240 --> 00:26:15,290 expect, which is, I can't say the same for 431 00:26:15,290 --> 00:26:18,290 IRB in that, in that case. 432 00:26:18,290 --> 00:26:20,560 I have this thing called bowling_game in there. Let's 433 00:26:20,560 --> 00:26:27,520 take a look at it. That looks correct to 434 00:26:27,520 --> 00:26:30,250 me. So let's just do that again. I'm gonna 435 00:26:30,250 --> 00:26:34,380 copy the history again. And then I'm gonna remove 436 00:26:34,380 --> 00:26:39,030 bowling_game, just to make sure that my script is 437 00:26:39,030 --> 00:26:45,190 doing what it promises, right. Oops. 438 00:26:45,190 --> 00:26:51,020 And it's not there anymore. So let's go back. 439 00:26:51,020 --> 00:26:58,020 Let's put in that, let's put in that implementation. 440 00:27:02,320 --> 00:27:06,150 And drop back in. Let's ask Pry to try 441 00:27:06,150 --> 00:27:12,130 again. No more exceptions. Do we have our bowling_game? 442 00:27:12,130 --> 00:27:14,210 We do. 443 00:27:14,210 --> 00:27:21,210 OK. So, what happened there, right? We used the 444 00:27:22,450 --> 00:27:27,750 debugger and the runtime as, as, as a tool 445 00:27:27,750 --> 00:27:32,380 for driving our development process and build our implementation. 446 00:27:32,380 --> 00:27:35,140 Not just to fix software, right. 447 00:27:35,140 --> 00:27:38,340 We validated our implementation before codifying it, and we 448 00:27:38,340 --> 00:27:42,350 reversed this traditional workflow that I've got so many 449 00:27:42,350 --> 00:27:47,010 problems with. We explored and we informed ourselves about 450 00:27:47,010 --> 00:27:52,700 how to, how to use our classes without context 451 00:27:52,700 --> 00:27:56,270 switching. Right, we stayed focused in one tool. And 452 00:27:56,270 --> 00:27:59,870 then we didn't have to reload our, our libraries 453 00:27:59,870 --> 00:28:02,460 and our environment every time we wanted to run 454 00:28:02,460 --> 00:28:05,920 code, so it was fast. 455 00:28:05,920 --> 00:28:11,330 So, and, you know. We're in the testing track 456 00:28:11,330 --> 00:28:13,370 here, so I should probably talk about testing a 457 00:28:13,370 --> 00:28:17,990 little bit. And, that might have felt a little 458 00:28:17,990 --> 00:28:19,850 bit like TDD to you. I mean, it does 459 00:28:19,850 --> 00:28:26,340 to me, right. As, as practitioners of TDD, you 460 00:28:26,340 --> 00:28:30,030 know, I may not, I'm, I'm, I love TDD. 461 00:28:30,030 --> 00:28:35,030 I think most, many Rubyists do. 462 00:28:35,030 --> 00:28:38,110 But I mean, what I love about it most 463 00:28:38,110 --> 00:28:41,320 is it keeps me focused and, and, and, having 464 00:28:41,320 --> 00:28:46,660 a test suite allows me to aggressively refactor my 465 00:28:46,660 --> 00:28:48,240 code, you know, and have the confidence to do 466 00:28:48,240 --> 00:28:50,610 that. You know, and I'd rather do that upfront 467 00:28:50,610 --> 00:28:54,300 than after the fact, right. But, as practitioners of 468 00:28:54,300 --> 00:28:59,190 TDD, you know, we've learned to love failure, you 469 00:28:59,190 --> 00:28:59,360 know. 470 00:28:59,360 --> 00:29:02,230 TDD is all about making something fail, then writing 471 00:29:02,230 --> 00:29:04,130 the code to make it pass. When we have 472 00:29:04,130 --> 00:29:08,030 bugs, we want to exercise that exact piece of 473 00:29:08,030 --> 00:29:11,190 code that's giving us the error and get that 474 00:29:11,190 --> 00:29:13,250 error, you know, before we then go, cause we 475 00:29:13,250 --> 00:29:15,010 know we're about to do something cool and fix 476 00:29:15,010 --> 00:29:16,750 it, right. 477 00:29:16,750 --> 00:29:21,730 So, we love to see red. And so a, 478 00:29:21,730 --> 00:29:26,200 a practice that's, that's centered around failure is naturally 479 00:29:26,200 --> 00:29:28,590 suited to a debugging tool, right. I mean, that's 480 00:29:28,590 --> 00:29:32,520 what a debugging tool does. It's meant to handle 481 00:29:32,520 --> 00:29:35,770 failures, catch failures, and then give you the tools 482 00:29:35,770 --> 00:29:38,750 you need and enable you to fix them as 483 00:29:38,750 --> 00:29:41,760 quickly as you can. And we've seen how awesome, 484 00:29:41,760 --> 00:29:45,060 you know, a debugger Pry can be. 485 00:29:45,060 --> 00:29:49,360 And, so, the promise of this talk is that 486 00:29:49,360 --> 00:29:53,220 I'm going to, you know, deliver a, a, a 487 00:29:53,220 --> 00:29:57,220 Pry-enabled TDD workflow. But before I do that, I 488 00:29:57,220 --> 00:29:59,850 mean, I mentioned that, you know, I've had a, 489 00:29:59,850 --> 00:30:04,340 kind of specific experience that made me a believer 490 00:30:04,340 --> 00:30:07,000 that this workflow even happens. I mean, I've actually 491 00:30:07,000 --> 00:30:10,350 done this before. I'm not creating this, right. 492 00:30:10,350 --> 00:30:14,750 And, and that specific experience was this. Does anybody 493 00:30:14,750 --> 00:30:19,910 know what this is? Smalltalk. Yeah. This is a 494 00:30:19,910 --> 00:30:24,990 screenshot of a Farrow Smalltalk IDE, right. And I 495 00:30:24,990 --> 00:30:29,250 spent about a year or so in the 2000s 496 00:30:29,250 --> 00:30:32,010 writing a web application in the C-side framework in 497 00:30:32,010 --> 00:30:35,200 Smalltalk for a company in New York City with, 498 00:30:35,200 --> 00:30:37,240 with a team of guys. 499 00:30:37,240 --> 00:30:41,740 And, really delving into object-oriented programming, and learning so 500 00:30:41,740 --> 00:30:44,830 much about it, I really learned to love this, 501 00:30:44,830 --> 00:30:48,910 right. But what first, what first struck me when 502 00:30:48,910 --> 00:30:52,250 I saw Pry and I saw the ls command 503 00:30:52,250 --> 00:30:57,060 was it reminded me of this, right. Right here, 504 00:30:57,060 --> 00:31:00,580 we are looking at a ZnClient class in a 505 00:31:00,580 --> 00:31:05,160 Zinc HTTP package. We see the class definition right 506 00:31:05,160 --> 00:31:07,730 there at the bottom, with all of the instance 507 00:31:07,730 --> 00:31:11,510 variables that this class makes use of listed out. 508 00:31:11,510 --> 00:31:13,930 On the right hand side, we see all the 509 00:31:13,930 --> 00:31:17,260 methods that we can call on this, on a, 510 00:31:17,260 --> 00:31:19,530 on an instance of class, and we can click 511 00:31:19,530 --> 00:31:22,860 on any of those to see the source code 512 00:31:22,860 --> 00:31:27,090 of that method. I mean, that's all, that's all 513 00:31:27,090 --> 00:31:31,340 you need, as far as I'm concerned. I mean, 514 00:31:31,340 --> 00:31:34,760 that gets you ninety percent of the way there 515 00:31:34,760 --> 00:31:38,750 almost every, like, almost every time, right. 516 00:31:38,750 --> 00:31:43,400 So, I wanted to, I wanted to demo, like 517 00:31:43,400 --> 00:31:46,040 a, a Smalltalk TDD workflow, cause that's the other 518 00:31:46,040 --> 00:31:49,580 really cool thing about Smalltalk and different thing about 519 00:31:49,580 --> 00:31:52,960 Smalltalk is that it really, like, enables this awesome 520 00:31:52,960 --> 00:31:55,270 TDD workflow. And I don't think I'm gonna have 521 00:31:55,270 --> 00:31:58,110 the time to do that unfortunately. 522 00:31:58,110 --> 00:32:04,870 But the TL;DR is this, basically. OK. So if 523 00:32:04,870 --> 00:32:07,970 I write a test, and I try to exercise 524 00:32:07,970 --> 00:32:14,020 a class that doesn't exist, like BowlingGame here, Smalltalk's, 525 00:32:14,020 --> 00:32:17,630 when I save this, Smalltalk's gonna say, that doesn't 526 00:32:17,630 --> 00:32:19,280 exist. Do you wanna, what do you want to 527 00:32:19,280 --> 00:32:20,460 do? 528 00:32:20,460 --> 00:32:23,990 And the first option there is define new class. 529 00:32:23,990 --> 00:32:27,850 You just click it and it does it, right. 530 00:32:27,850 --> 00:32:30,410 When I try to call a method on that 531 00:32:30,410 --> 00:32:36,240 class that doesn't exist, Smalltalk asks me if I 532 00:32:36,240 --> 00:32:39,990 want to implement that method, and when I say 533 00:32:39,990 --> 00:32:44,250 yes, it drops me into a debugger, right. A 534 00:32:44,250 --> 00:32:47,630 runtime, where I have everything available I need to 535 00:32:47,630 --> 00:32:50,100 create the implementation of that class, and I can 536 00:32:50,100 --> 00:32:52,650 expect all the things I need to do so. 537 00:32:52,650 --> 00:32:56,340 Right, I'm not in a static code editor here. 538 00:32:56,340 --> 00:33:00,970 This is like, living system, right. So I can 539 00:33:00,970 --> 00:33:03,830 do so. Just want to return zero. And when 540 00:33:03,830 --> 00:33:08,980 I save, my tests pass. So that's. That's, that's 541 00:33:08,980 --> 00:33:13,010 the idea, right. And, and it, it's small, but, 542 00:33:13,010 --> 00:33:17,190 you know, small changes in your user interface, you 543 00:33:17,190 --> 00:33:20,630 know, can really turn, like a daunting experience into 544 00:33:20,630 --> 00:33:23,290 a really motivating flow, right. 545 00:33:23,290 --> 00:33:25,870 It doesn't take much. 546 00:33:25,870 --> 00:33:29,650 So, when I talk about, you know, this power 547 00:33:29,650 --> 00:33:31,830 of Pry and, and we've talked about some of 548 00:33:31,830 --> 00:33:35,980 the plugins and how powerful they are and how, 549 00:33:35,980 --> 00:33:39,630 you know, Pry is so easy to extend, you 550 00:33:39,630 --> 00:33:43,680 know, even I can do it. And, and so, 551 00:33:43,680 --> 00:33:46,350 I've kind of gotten the ball rolling. 552 00:33:46,350 --> 00:33:51,770 I pushed a little code up to GitHub. It 553 00:33:51,770 --> 00:33:55,270 defines a new command called define-it in Pry. Right 554 00:33:55,270 --> 00:33:57,860 now, it's just a PryRC, and you can define 555 00:33:57,860 --> 00:34:00,000 Pry commands in your PryRC or you can do 556 00:34:00,000 --> 00:34:03,470 gems or whatever, and that's, that's where I want 557 00:34:03,470 --> 00:34:05,360 to move it. 558 00:34:05,360 --> 00:34:09,119 But, this is my attempt to kind of get 559 00:34:09,119 --> 00:34:16,119 this workflow going in, in Ruby, right. So, all 560 00:34:22,280 --> 00:34:27,590 right. So here it is. Here's my PryRC. I'm 561 00:34:27,590 --> 00:34:33,429 creating a command called define-it, and then I'm implementing 562 00:34:33,429 --> 00:34:38,250 - every Pry command implements this method called process, 563 00:34:38,250 --> 00:34:40,290 and that is what is going to happen when 564 00:34:40,290 --> 00:34:43,168 you call the command from within the Pry REPL, 565 00:34:43,168 --> 00:34:43,949 right. 566 00:34:43,949 --> 00:34:45,980 And so I'm kind of using this idea that 567 00:34:45,980 --> 00:34:50,179 we demoed in the last demo of, when I 568 00:34:50,179 --> 00:34:52,940 hit a name error, I just want to automatically 569 00:34:52,940 --> 00:34:57,510 generate an empty class definition and move on. What 570 00:34:57,510 --> 00:34:59,000 it will also do is when I hit a 571 00:34:59,000 --> 00:35:05,230 NoMethodError, it's gonna generate an empty method definition and 572 00:35:05,230 --> 00:35:07,210 put you right in there where you need to 573 00:35:07,210 --> 00:35:11,990 be to implement it, right. 574 00:35:11,990 --> 00:35:18,990 So let's take a look. So, once again. Oh, 575 00:35:19,080 --> 00:35:23,490 let me just show you this real quick, though. 576 00:35:23,490 --> 00:35:25,770 So here is a spec and a set of 577 00:35:25,770 --> 00:35:29,790 tests that exercise this BowlingGame class, right. The first 578 00:35:29,790 --> 00:35:34,560 test just verifies that BowlingGame is a thing. The 579 00:35:34,560 --> 00:35:37,710 second test says if I ask a new BowlingGame 580 00:35:37,710 --> 00:35:40,840 for its score, it should return zero. The third 581 00:35:40,840 --> 00:35:43,430 test says, if I bowl a four then the 582 00:35:43,430 --> 00:35:46,290 game's score should reflect that. 583 00:35:46,290 --> 00:35:50,580 And the last test says, if I bowl twice, 584 00:35:50,580 --> 00:35:54,440 you know, the, the score should reflect that, that 585 00:35:54,440 --> 00:36:01,440 sum. So, when I run rSpec under pry-rescue, pry-rescue, 586 00:36:07,120 --> 00:36:10,640 you know, it does different things in different contexts, 587 00:36:10,640 --> 00:36:14,950 right. So just like before, pry-rescue's gonna break on 588 00:36:14,950 --> 00:36:19,700 unhandled exceptions, just like it always has done, but 589 00:36:19,700 --> 00:36:23,040 in the context of rSpec, it's also gonna break 590 00:36:23,040 --> 00:36:25,580 on assertion failures, all right. So you can poke 591 00:36:25,580 --> 00:36:28,040 around and get those fixed. 592 00:36:28,040 --> 00:36:34,210 So, here we are. We. We've got our first 593 00:36:34,210 --> 00:36:41,210 exception, right. It's the name error. Uninitialized constant BowlingGame. 594 00:36:41,880 --> 00:36:45,670 So let's define it. 595 00:36:45,670 --> 00:36:52,520 All right. Didn't see it, but it did it. 596 00:36:52,520 --> 00:36:56,290 Next. Believe me. 597 00:36:56,290 --> 00:37:01,450 All right. So next. Next, we've got our next 598 00:37:01,450 --> 00:37:04,720 exception here right. Undefined method 'score' for BowlingGame. Our 599 00:37:04,720 --> 00:37:10,500 NoMethodError. So let's define-it. You guys didn't believe me, 600 00:37:10,500 --> 00:37:13,710 but there it is. All right. There we go. 601 00:37:13,710 --> 00:37:18,370 We're in our empty method. Let's TDD, right. We 602 00:37:18,370 --> 00:37:20,350 just need to make the test pass so we 603 00:37:20,350 --> 00:37:23,650 return zero out of there. Ask pry-rescue to try 604 00:37:23,650 --> 00:37:28,730 again. We got another exception here. NoMethodError: undefined method 605 00:37:28,730 --> 00:37:30,210 'bowl' for BowlingGame. 606 00:37:30,210 --> 00:37:34,180 So, let's define-it. Now I feel like we're gonna 607 00:37:34,180 --> 00:37:37,550 need to keep track of a little state, so 608 00:37:37,550 --> 00:37:44,550 let's. We want to make that the fixnum. 609 00:37:46,450 --> 00:37:49,860 We want to return @score out of here now, 610 00:37:49,860 --> 00:37:56,460 instead. And let's initialize @score to be zero when 611 00:37:56,460 --> 00:38:02,790 you create a new BowlingGame. Let's save that and 612 00:38:02,790 --> 00:38:03,830 let's try again. 613 00:38:03,830 --> 00:38:08,090 All right. That worked. We're in our last test 614 00:38:08,090 --> 00:38:11,780 here, and we've hit our first assertion error, right. 615 00:38:11,780 --> 00:38:14,650 It expected nine and it got five, cause we're 616 00:38:14,650 --> 00:38:18,570 not doing any of the, the totaling yet. So 617 00:38:18,570 --> 00:38:23,540 let's, this is another way you can call edit. 618 00:38:23,540 --> 00:38:27,130 You can just ask it to edit the class, 619 00:38:27,130 --> 00:38:30,690 and it'll know what file to drop into. So 620 00:38:30,690 --> 00:38:32,280 I feel like we're gonna want to keep track 621 00:38:32,280 --> 00:38:35,420 of our scores now. So let's just push those 622 00:38:35,420 --> 00:38:40,640 fixnums on a scores array. Let's get our score 623 00:38:40,640 --> 00:38:44,480 by reducing those values. That's how you keep score 624 00:38:44,480 --> 00:38:47,220 in bowling, right. You just add everything up. All 625 00:38:47,220 --> 00:38:48,570 right. Cool. 626 00:38:48,570 --> 00:38:53,280 And let's, let's initialize it with an array with 627 00:38:53,280 --> 00:38:58,890 initial value of zero as well. Let's try again. 628 00:38:58,890 --> 00:39:05,890 Something's wrong there. There it is. 629 00:39:07,080 --> 00:39:14,080 All right. Four examples, zero failures. rSpec thought we 630 00:39:14,840 --> 00:39:21,840 didn't fail at all, you know. It's pretty cool. 631 00:39:25,340 --> 00:39:32,340 So. So what happened there? All right. I mean, 632 00:39:34,080 --> 00:39:40,130 basically, you know, we. We, again, we used Pry 633 00:39:40,130 --> 00:39:44,580 to drive our development process. We used our own 634 00:39:44,580 --> 00:39:47,700 Pry plugin there to kind of make that a 635 00:39:47,700 --> 00:39:52,390 little bit easier, and within one runtime, we fixed 636 00:39:52,390 --> 00:39:56,890 all of our assertions, exercised our class and implemented 637 00:39:56,890 --> 00:39:58,590 the whole solution, right. 638 00:39:58,590 --> 00:40:01,730 No reloading, no nothing like that. 639 00:40:01,730 --> 00:40:08,730 So, in conclusion, embrace your runtime and all things. 640 00:40:10,150 --> 00:40:14,570 Don't read the effing manual. 641 00:40:14,570 --> 00:40:20,920 Use a kickass flashlight. 642 00:40:20,920 --> 00:40:24,340 If you're fixing software, use a debugger. If you're 643 00:40:24,340 --> 00:40:27,850 building software, use a debugger. And when you use 644 00:40:27,850 --> 00:40:30,369 a debugger, use Pry. 645 00:40:30,369 --> 00:40:32,369 Thank you very much.