[Script Info] Title: [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:17.80,0:00:21.97,Default,,0000,0000,0000,,JOEL TURNBULL: Thanks for coming. Dialogue: 0,0:00:21.97,0:00:23.73,Default,,0000,0000,0000,,My name is Joel Turnbull. Dialogue: 0,0:00:23.73,0:00:26.40,Default,,0000,0000,0000,,I'm a developer for Gaslight in Cincinnatti,\NOhio. Dialogue: 0,0:00:26.40,0:00:30.45,Default,,0000,0000,0000,,I also head up and coordinate a blog over\Nthere, Dialogue: 0,0:00:30.45,0:00:33.41,Default,,0000,0000,0000,,in case anybody ever wants to talk about that. Dialogue: 0,0:00:33.41,0:00:36.77,Default,,0000,0000,0000,,But today, I'm here to talk about debugger\Ndriven Dialogue: 0,0:00:36.77,0:00:43.77,Default,,0000,0000,0000,,development with Pry. Most Rubyists I know\Ndon't use Dialogue: 0,0:00:44.32,0:00:51.28,Default,,0000,0000,0000,,debuggers. Rubyists I know, when faced with\Na problem, Dialogue: 0,0:00:51.28,0:00:56.55,Default,,0000,0000,0000,,would prefer to ponder code than pop open\Na Dialogue: 0,0:00:56.55,0:00:59.44,Default,,0000,0000,0000,,debugger and poke around. Dialogue: 0,0:00:59.44,0:01:02.51,Default,,0000,0000,0000,,This is crazy to me. I've always thought it Dialogue: 0,0:01:02.51,0:01:05.88,Default,,0000,0000,0000,,was, because to me, trying to solve a problem Dialogue: 0,0:01:05.88,0:01:09.67,Default,,0000,0000,0000,,by pondering code is like trying to find your Dialogue: 0,0:01:09.67,0:01:13.92,Default,,0000,0000,0000,,keys in the dark, when you're holding a flashlight, Dialogue: 0,0:01:13.92,0:01:19.77,Default,,0000,0000,0000,,but you're consciously deciding not to use\Nit. Dialogue: 0,0:01:19.77,0:01:22.19,Default,,0000,0000,0000,,So why is this? I, I used to think Dialogue: 0,0:01:22.19,0:01:24.56,Default,,0000,0000,0000,,it might be about egos or culture or something Dialogue: 0,0:01:24.56,0:01:28.13,Default,,0000,0000,0000,,like that, but really it's pretty simple.\NI think Dialogue: 0,0:01:28.13,0:01:30.42,Default,,0000,0000,0000,,we've had a lack of really good tools up Dialogue: 0,0:01:30.42,0:01:36.69,Default,,0000,0000,0000,,to this point. But ultimately, my talk isn't\Nabout Dialogue: 0,0:01:36.69,0:01:40.74,Default,,0000,0000,0000,,using debuggers in a traditional sense to\Nfix software, Dialogue: 0,0:01:40.74,0:01:44.25,Default,,0000,0000,0000,,but using debuggers as a tool in your workflow Dialogue: 0,0:01:44.25,0:01:47.09,Default,,0000,0000,0000,,to build software. Dialogue: 0,0:01:47.09,0:01:51.00,Default,,0000,0000,0000,,And, so why do I think we can do Dialogue: 0,0:01:51.00,0:01:55.44,Default,,0000,0000,0000,,this right now? I feel like we finally have Dialogue: 0,0:01:55.44,0:01:59.93,Default,,0000,0000,0000,,a tool that we can use to explore this Dialogue: 0,0:01:59.93,0:02:06.49,Default,,0000,0000,0000,,debugger driven, debugger driven workflow.\NAnd that tool is Dialogue: 0,0:02:06.49,0:02:06.86,Default,,0000,0000,0000,,Pry. Dialogue: 0,0:02:06.86,0:02:09.19,Default,,0000,0000,0000,,Can I get a show of hands of who Dialogue: 0,0:02:09.19,0:02:16.19,Default,,0000,0000,0000,,uses Pry? Awesome. Like, everybody. All right.\NCool. So Dialogue: 0,0:02:16.97,0:02:21.49,Default,,0000,0000,0000,,I'm talking about debugger driven development\Nwith Pry. Conrad Dialogue: 0,0:02:21.49,0:02:23.92,Default,,0000,0000,0000,,Erwin gave a talk not even like six months Dialogue: 0,0:02:23.92,0:02:26.88,Default,,0000,0000,0000,,ago called REPL Driven Development with Pry.\NI swear Dialogue: 0,0:02:26.88,0:02:28.85,Default,,0000,0000,0000,,to god I had no idea. Dialogue: 0,0:02:28.85,0:02:35.85,Default,,0000,0000,0000,,But, and both are accurate, I think. You know, Dialogue: 0,0:02:36.84,0:02:39.56,Default,,0000,0000,0000,,but I think both terms kind of undersell what Dialogue: 0,0:02:39.56,0:02:42.14,Default,,0000,0000,0000,,the power of Pry is. So here's my favorite Dialogue: 0,0:02:42.14,0:02:47.10,Default,,0000,0000,0000,,definition. Pry is an IRB alternative and\Nruntime developer Dialogue: 0,0:02:47.10,0:02:49.66,Default,,0000,0000,0000,,console. So if we take the first part of Dialogue: 0,0:02:49.66,0:02:53.61,Default,,0000,0000,0000,,that and we think about Pry as an IRB Dialogue: 0,0:02:53.61,0:02:57.99,Default,,0000,0000,0000,,alternative, you know, anything that you can\Ndo with, Dialogue: 0,0:02:57.99,0:03:02.93,Default,,0000,0000,0000,,with, both, both are REPLs, right. And, and\Na Dialogue: 0,0:03:02.93,0:03:05.46,Default,,0000,0000,0000,,debugger is a REPL, too. Anything you can\Ndo Dialogue: 0,0:03:05.46,0:03:08.35,Default,,0000,0000,0000,,in Ruby, you can do in IRB. Anything you Dialogue: 0,0:03:08.35,0:03:11.90,Default,,0000,0000,0000,,can do in IRB, you can do in Pry. Dialogue: 0,0:03:11.90,0:03:15.29,Default,,0000,0000,0000,,What makes both of them powerful, is they\Nboth Dialogue: 0,0:03:15.29,0:03:20.62,Default,,0000,0000,0000,,leverage this idea of runtime. And, to me,\Nruntime Dialogue: 0,0:03:20.62,0:03:24.44,Default,,0000,0000,0000,,is all about immersion. It's about being immersed\Nin Dialogue: 0,0:03:24.44,0:03:28.59,Default,,0000,0000,0000,,a live system, where you can play with code Dialogue: 0,0:03:28.59,0:03:30.58,Default,,0000,0000,0000,,and you can look at your objects and, and Dialogue: 0,0:03:30.58,0:03:33.92,Default,,0000,0000,0000,,all that kind of thing. You can validate your Dialogue: 0,0:03:33.92,0:03:40.92,Default,,0000,0000,0000,,implementations. Everything you need to do.\NAnd it's like, Dialogue: 0,0:03:42.29,0:03:45.02,Default,,0000,0000,0000,,looking for your keys with a flashlight. Dialogue: 0,0:03:45.02,0:03:49.14,Default,,0000,0000,0000,,So, given that Pry and IRB are both REPLs Dialogue: 0,0:03:49.14,0:03:51.10,Default,,0000,0000,0000,,and they both have this idea of runtime, why Dialogue: 0,0:03:51.10,0:03:56.52,Default,,0000,0000,0000,,should you use Pry instead of IRB? It's got Dialogue: 0,0:03:56.52,0:03:59.28,Default,,0000,0000,0000,,a couple vital workflow features right out\Nof the Dialogue: 0,0:03:59.28,0:04:03.75,Default,,0000,0000,0000,,box. Syntax highlighting and tab completion.\NBoth super handy. Dialogue: 0,0:04:03.75,0:04:06.62,Default,,0000,0000,0000,,But, what I want to talk about today is Dialogue: 0,0:04:06.62,0:04:11.49,Default,,0000,0000,0000,,some of the bigger, game-changing features\Nof Pry. The Dialogue: 0,0:04:11.49,0:04:18.49,Default,,0000,0000,0000,,first one is enhanced introspection. Here's\Nour friend again. Dialogue: 0,0:04:19.22,0:04:21.85,Default,,0000,0000,0000,,Introspection is the ability to, of, of a\Nlanguage, Dialogue: 0,0:04:21.85,0:04:25.21,Default,,0000,0000,0000,,where you can ask a language questions about\Nitself. Dialogue: 0,0:04:25.21,0:04:29.25,Default,,0000,0000,0000,,And it's built into Ruby, and that's awesome. Dialogue: 0,0:04:29.25,0:04:31.97,Default,,0000,0000,0000,,If you've ever asked a class what method you Dialogue: 0,0:04:31.97,0:04:34.68,Default,,0000,0000,0000,,can call on it, or you've asked an instance Dialogue: 0,0:04:34.68,0:04:41.45,Default,,0000,0000,0000,,what class it is, you're doing introspection. Dialogue: 0,0:04:41.45,0:04:42.94,Default,,0000,0000,0000,,What if you want to go deeper? Like, what Dialogue: 0,0:04:42.94,0:04:44.86,Default,,0000,0000,0000,,if you want to know what the class methods Dialogue: 0,0:04:44.86,0:04:47.38,Default,,0000,0000,0000,,are versus the instance methods? You know,\Nwhat if Dialogue: 0,0:04:47.38,0:04:50.86,Default,,0000,0000,0000,,you want to know what methods are inherited,\Nand Dialogue: 0,0:04:50.86,0:04:52.61,Default,,0000,0000,0000,,from where? What if you want to know what Dialogue: 0,0:04:52.61,0:04:58.10,Default,,0000,0000,0000,,state an instance holds onto during its life\Ncycle? Dialogue: 0,0:04:58.10,0:05:00.85,Default,,0000,0000,0000,,You can answer all these questions with plain\NRuby Dialogue: 0,0:05:00.85,0:05:05.29,Default,,0000,0000,0000,,and IRB. But the problem is, is that, it's, Dialogue: 0,0:05:05.29,0:05:09.06,Default,,0000,0000,0000,,the, the amount of effort involved is non-trivial.\NI Dialogue: 0,0:05:09.06,0:05:14.50,Default,,0000,0000,0000,,would classify it as daunting. Dialogue: 0,0:05:14.50,0:05:21.50,Default,,0000,0000,0000,,So. Given that. You know. I would, I would Dialogue: 0,0:05:29.05,0:05:35.40,Default,,0000,0000,0000,,classify this as DRTFM. This is what I, this Dialogue: 0,0:05:35.40,0:05:40.71,Default,,0000,0000,0000,,is what I point to. I mean, this is Dialogue: 0,0:05:40.71,0:05:44.29,Default,,0000,0000,0000,,the workflow that I like. Dialogue: 0,0:05:44.29,0:05:46.94,Default,,0000,0000,0000,,I like to take the things out of the Dialogue: 0,0:05:46.94,0:05:48.54,Default,,0000,0000,0000,,box. I like to get a feel for what Dialogue: 0,0:05:48.54,0:05:51.82,Default,,0000,0000,0000,,the pieces are. I like to play around with Dialogue: 0,0:05:51.82,0:05:54.30,Default,,0000,0000,0000,,them. I like to try to put it together Dialogue: 0,0:05:54.30,0:05:56.89,Default,,0000,0000,0000,,without reading the manual, and if I get stuck, Dialogue: 0,0:05:56.89,0:06:01.09,Default,,0000,0000,0000,,then I read the manual, right. Dialogue: 0,0:06:01.09,0:06:06.23,Default,,0000,0000,0000,,The second really game-changing feature of\NPry, to me, Dialogue: 0,0:06:06.23,0:06:10.44,Default,,0000,0000,0000,,is extendability through plugins. And the\Nbest way that Dialogue: 0,0:06:10.44,0:06:13.51,Default,,0000,0000,0000,,I can show this is to just demo some Dialogue: 0,0:06:13.51,0:06:18.14,Default,,0000,0000,0000,,of my favorites for you. Dialogue: 0,0:06:18.14,0:06:24.08,Default,,0000,0000,0000,,So, I'm gonna show you a Rails app. Instead Dialogue: 0,0:06:24.08,0:06:27.70,Default,,0000,0000,0000,,of calling it in a normal way, like rails Dialogue: 0,0:06:27.70,0:06:31.74,Default,,0000,0000,0000,,s, I'm gonna call it like this. Under the Dialogue: 0,0:06:31.74,0:06:34.55,Default,,0000,0000,0000,,umbrella of Pry rescue. And I'll show you\Nwhy Dialogue: 0,0:06:34.55,0:06:40.33,Default,,0000,0000,0000,,in a minute. Dialogue: 0,0:06:40.33,0:06:43.45,Default,,0000,0000,0000,,But here we are. This is an app I've Dialogue: 0,0:06:43.45,0:06:46.30,Default,,0000,0000,0000,,been working on late, late nights, you know.\NPlease Dialogue: 0,0:06:46.30,0:06:50.40,Default,,0000,0000,0000,,don't steal this. This is a bowling score\Ncount, Dialogue: 0,0:06:50.40,0:06:53.41,Default,,0000,0000,0000,,tracker, right. You can push any number after\Nyou Dialogue: 0,0:06:53.41,0:06:56.29,Default,,0000,0000,0000,,bowl and it will record what you, what, how Dialogue: 0,0:06:56.29,0:06:59.03,Default,,0000,0000,0000,,many pins you knocked down, right. Dialogue: 0,0:06:59.03,0:07:01.43,Default,,0000,0000,0000,,So, the first thing I'm gonna show you about Dialogue: 0,0:07:01.43,0:07:08.43,Default,,0000,0000,0000,,Pry, for those who aren't necessarily familiar,\Nis how Dialogue: 0,0:07:09.97,0:07:15.32,Default,,0000,0000,0000,,you invoke a runtime at any point in your Dialogue: 0,0:07:15.32,0:07:18.52,Default,,0000,0000,0000,,application, where you're running Ruby, right. Dialogue: 0,0:07:18.52,0:07:22.05,Default,,0000,0000,0000,,Here, I've inserted a couple binding dot prys.\NOne Dialogue: 0,0:07:22.05,0:07:24.100,Default,,0000,0000,0000,,into my controller action and one into my\Ntemplate. Dialogue: 0,0:07:24.100,0:07:28.03,Default,,0000,0000,0000,,On the lower left we have our model. OK, Dialogue: 0,0:07:28.03,0:07:32.07,Default,,0000,0000,0000,,so let's rerun it with that in mind. Dialogue: 0,0:07:32.07,0:07:34.36,Default,,0000,0000,0000,,Let's go back to our running server, and we'll Dialogue: 0,0:07:34.36,0:07:38.18,Default,,0000,0000,0000,,see that we've halted our execution here,\Nand we've Dialogue: 0,0:07:38.18,0:07:40.52,Default,,0000,0000,0000,,been dropped into a run time. And we can Dialogue: 0,0:07:40.52,0:07:45.71,Default,,0000,0000,0000,,do things in here like look around. We can Dialogue: 0,0:07:45.71,0:07:48.26,Default,,0000,0000,0000,,play lines of code. Let's play the line that Dialogue: 0,0:07:48.26,0:07:52.22,Default,,0000,0000,0000,,sets the bowling game. And then we can look Dialogue: 0,0:07:52.22,0:07:54.82,Default,,0000,0000,0000,,again. Dialogue: 0,0:07:54.82,0:07:57.14,Default,,0000,0000,0000,,When we exit from this, we've returned from\Nour Dialogue: 0,0:07:57.14,0:08:00.15,Default,,0000,0000,0000,,controller. We're starting to render our template,\Nand we've Dialogue: 0,0:08:00.15,0:08:02.49,Default,,0000,0000,0000,,hit our next binding dot pry. You can put Dialogue: 0,0:08:02.49,0:08:07.15,Default,,0000,0000,0000,,binding dot prys inside your erb tags, right. Dialogue: 0,0:08:07.15,0:08:10.11,Default,,0000,0000,0000,,Same drill. We can look at bowling games.\NWe Dialogue: 0,0:08:10.11,0:08:17.11,Default,,0000,0000,0000,,can, we can step into our next, our, our, Dialogue: 0,0:08:18.36,0:08:21.02,Default,,0000,0000,0000,,our implementations of our methods. Here we've\Nstepped into Dialogue: 0,0:08:21.02,0:08:24.86,Default,,0000,0000,0000,,the frames method of our bowling game model. Dialogue: 0,0:08:24.86,0:08:29.50,Default,,0000,0000,0000,,Same drill. We can look around here. We can Dialogue: 0,0:08:29.50,0:08:33.98,Default,,0000,0000,0000,,look at ourself. We can go to the next, Dialogue: 0,0:08:33.98,0:08:38.69,Default,,0000,0000,0000,,or we can continue. Dialogue: 0,0:08:38.69,0:08:43.78,Default,,0000,0000,0000,,So, you can see how handy that would be Dialogue: 0,0:08:43.78,0:08:48.65,Default,,0000,0000,0000,,if things aren't necessarily blowing up, but,\Nyou know, Dialogue: 0,0:08:48.65,0:08:55.65,Default,,0000,0000,0000,,something's not quite right, either. So what\Nif things Dialogue: 0,0:08:56.94,0:09:00.71,Default,,0000,0000,0000,,do blow up, though? Right. Dialogue: 0,0:09:00.71,0:09:04.54,Default,,0000,0000,0000,,So, here I am. I'm gonna, I'm gonna spark Dialogue: 0,0:09:04.54,0:09:07.94,Default,,0000,0000,0000,,an exception here by bullet, trying to bowl\Nthe Dialogue: 0,0:09:07.94,0:09:11.27,Default,,0000,0000,0000,,next ball of my next frame. I'm gonna bowl Dialogue: 0,0:09:11.27,0:09:14.91,Default,,0000,0000,0000,,a big nine. I'm gonna come back here and Dialogue: 0,0:09:14.91,0:09:18.75,Default,,0000,0000,0000,,we've been dropped into a runtime, because\Nan exception Dialogue: 0,0:09:18.75,0:09:22.24,Default,,0000,0000,0000,,was thrown. That's what being under the watchful\Neye Dialogue: 0,0:09:22.24,0:09:25.12,Default,,0000,0000,0000,,of Pry rescue is gonna do for us within Dialogue: 0,0:09:25.12,0:09:27.73,Default,,0000,0000,0000,,this context here. Dialogue: 0,0:09:27.73,0:09:33.23,Default,,0000,0000,0000,,So, some interesting, interesting things we\Ncan do here. Dialogue: 0,0:09:33.23,0:09:36.09,Default,,0000,0000,0000,,We can call the show-stack command of the\NPry Dialogue: 0,0:09:36.09,0:09:40.54,Default,,0000,0000,0000,,stack explorer plugin. And we're seeing the\Nwhole stack Dialogue: 0,0:09:40.54,0:09:44.88,Default,,0000,0000,0000,,here. this is like caller, but it's alive,\Nright. Dialogue: 0,0:09:44.88,0:09:49.26,Default,,0000,0000,0000,,We can move up the stack. We can move Dialogue: 0,0:09:49.26,0:09:52.13,Default,,0000,0000,0000,,up the stack nine frames. We can move down Dialogue: 0,0:09:52.13,0:09:54.38,Default,,0000,0000,0000,,the stack. We can take a look at the Dialogue: 0,0:09:54.38,0:09:58.54,Default,,0000,0000,0000,,state of any object here at any level of Dialogue: 0,0:09:58.54,0:10:00.47,Default,,0000,0000,0000,,our stack trace. Dialogue: 0,0:10:00.47,0:10:02.06,Default,,0000,0000,0000,,We can look at our stack again just to Dialogue: 0,0:10:02.06,0:10:05.36,Default,,0000,0000,0000,,see where we're at. We're on frame ten. But Dialogue: 0,0:10:05.36,0:10:07.61,Default,,0000,0000,0000,,this is a big hairy kind of Rails stack Dialogue: 0,0:10:07.61,0:10:09.02,Default,,0000,0000,0000,,trace, and we're not getting a whole lot of Dialogue: 0,0:10:09.02,0:10:11.31,Default,,0000,0000,0000,,value out of that right now. Dialogue: 0,0:10:11.31,0:10:15.44,Default,,0000,0000,0000,,So let's call the cd-cause command of Pry\Nrescue. Dialogue: 0,0:10:15.44,0:10:18.77,Default,,0000,0000,0000,,And see if it can track down what caused Dialogue: 0,0:10:18.77,0:10:23.27,Default,,0000,0000,0000,,this problem in the first place. Dialogue: 0,0:10:23.27,0:10:25.40,Default,,0000,0000,0000,,There we go. This looks more familiar, right.\NHere Dialogue: 0,0:10:25.40,0:10:28.99,Default,,0000,0000,0000,,we are in our template. And I will guess Dialogue: 0,0:10:28.99,0:10:32.04,Default,,0000,0000,0000,,that on line thirteen we have a problem with Dialogue: 0,0:10:32.04,0:10:35.45,Default,,0000,0000,0000,,frame one. And that's true. So we just need Dialogue: 0,0:10:35.45,0:10:36.71,Default,,0000,0000,0000,,to add a little bit of a guard in Dialogue: 0,0:10:36.71,0:10:40.40,Default,,0000,0000,0000,,here, and say, you know, if we have pins Dialogue: 0,0:10:40.40,0:10:44.05,Default,,0000,0000,0000,,on frame one, let's render that. Otherwise\Nlet's just Dialogue: 0,0:10:44.05,0:10:46.26,Default,,0000,0000,0000,,render a dash. Dialogue: 0,0:10:46.26,0:10:48.96,Default,,0000,0000,0000,,And we get feedback that that's going, that's\Nwhat's Dialogue: 0,0:10:48.96,0:10:52.02,Default,,0000,0000,0000,,gonna happen, right. We know that this is\Na Dialogue: 0,0:10:52.02,0:10:54.20,Default,,0000,0000,0000,,working implementation. Dialogue: 0,0:10:54.20,0:10:57.38,Default,,0000,0000,0000,,So let's copy our history. This is another\Nplugin Dialogue: 0,0:10:57.38,0:11:01.72,Default,,0000,0000,0000,,called Pry clipboard. That's gonna copy that\Nimplementation into Dialogue: 0,0:11:01.72,0:11:06.47,Default,,0000,0000,0000,,my clipboard. I'm gonna edit a file where\Nthe Dialogue: 0,0:11:06.47,0:11:10.53,Default,,0000,0000,0000,,last exception was raised. It drops me right\Nwhere Dialogue: 0,0:11:10.53,0:11:13.22,Default,,0000,0000,0000,,I need to be. I'm gonna paste in that Dialogue: 0,0:11:13.22,0:11:20.22,Default,,0000,0000,0000,,implementation, drop back in, and I'm gonna\Nask Pry Dialogue: 0,0:11:23.18,0:11:24.57,Default,,0000,0000,0000,,rescue to try it again. Dialogue: 0,0:11:24.57,0:11:31.57,Default,,0000,0000,0000,,And we're back. And we've got our dash. So, Dialogue: 0,0:11:31.62,0:11:35.90,Default,,0000,0000,0000,,and we can continue to bowl, right. That's\Nlegit, Dialogue: 0,0:11:35.90,0:11:42.90,Default,,0000,0000,0000,,right. A five and a six. OK, cool. Dialogue: 0,0:11:44.67,0:11:51.48,Default,,0000,0000,0000,,So, what do we do here? We used binding Dialogue: 0,0:11:51.48,0:11:54.48,Default,,0000,0000,0000,,dot pry to invoke a runtime anywhere in our Dialogue: 0,0:11:54.48,0:11:58.29,Default,,0000,0000,0000,,app where we're doing Ruby code. We used the Dialogue: 0,0:11:58.29,0:12:02.81,Default,,0000,0000,0000,,pry-debugger gem to give us our step, next,\Nand Dialogue: 0,0:12:02.81,0:12:05.70,Default,,0000,0000,0000,,continue functionality that we expect out\Nof our debugging Dialogue: 0,0:12:05.70,0:12:09.38,Default,,0000,0000,0000,,tools. We used pry-rescue and ran our Rails\Napp Dialogue: 0,0:12:09.38,0:12:11.88,Default,,0000,0000,0000,,under the umbrella of pry-rescue to drop us\Ninto Dialogue: 0,0:12:11.88,0:12:13.92,Default,,0000,0000,0000,,a runtime when things go wrong, so that we Dialogue: 0,0:12:13.92,0:12:17.75,Default,,0000,0000,0000,,can poke around. We used the pry-stack_explorer\Ngem to Dialogue: 0,0:12:17.75,0:12:22.17,Default,,0000,0000,0000,,navigate the stack and explore state at any\Nlevel. Dialogue: 0,0:12:22.17,0:12:27.11,Default,,0000,0000,0000,,A few commands we saw were cd-cause in pry-rescue Dialogue: 0,0:12:27.11,0:12:30.27,Default,,0000,0000,0000,,that took us to the, the root of our Dialogue: 0,0:12:30.27,0:12:36.87,Default,,0000,0000,0000,,problem. We used play and we used copy-history\Nto Dialogue: 0,0:12:36.87,0:12:40.68,Default,,0000,0000,0000,,not mess around with, you know, copying things\Nwith Dialogue: 0,0:12:40.68,0:12:44.03,Default,,0000,0000,0000,,our mouse and pasting them into our REPL,\Nwhich Dialogue: 0,0:12:44.03,0:12:47.06,Default,,0000,0000,0000,,can be a pain. We used the edit command Dialogue: 0,0:12:47.06,0:12:49.15,Default,,0000,0000,0000,,with the e flag to take us to the Dialogue: 0,0:12:49.15,0:12:51.38,Default,,0000,0000,0000,,file where the exception occurred so that\Nwe could Dialogue: 0,0:12:51.38,0:12:56.93,Default,,0000,0000,0000,,fix it. And then we used pry-rescue, try-again,\Nwhich Dialogue: 0,0:12:56.93,0:13:01.85,Default,,0000,0000,0000,,under this, under the context of Rails, just\Nreplayed Dialogue: 0,0:13:01.85,0:13:04.60,Default,,0000,0000,0000,,our request. We didn't have to reload our,\Nour Dialogue: 0,0:13:04.60,0:13:08.37,Default,,0000,0000,0000,,page, or do any of that nonsense. Reload the Dialogue: 0,0:13:08.37,0:13:11.54,Default,,0000,0000,0000,,whole environment or anything like that, right.\NSo it Dialogue: 0,0:13:11.54,0:13:13.28,Default,,0000,0000,0000,,was fast. Dialogue: 0,0:13:13.28,0:13:18.56,Default,,0000,0000,0000,,So, the, that's, that's great, and having\Ndemoed Pry Dialogue: 0,0:13:18.56,0:13:20.74,Default,,0000,0000,0000,,in a debugger context, you know, I can show Dialogue: 0,0:13:20.74,0:13:24.07,Default,,0000,0000,0000,,some of those things. But, really, what I\Nfind Dialogue: 0,0:13:24.07,0:13:27.16,Default,,0000,0000,0000,,interesting is this idea of Pry as a runtime Dialogue: 0,0:13:27.16,0:13:30.84,Default,,0000,0000,0000,,developer console, right. Dialogue: 0,0:13:30.84,0:13:34.59,Default,,0000,0000,0000,,So there's some really awspect- really awesome\Naspects of Dialogue: 0,0:13:34.59,0:13:37.02,Default,,0000,0000,0000,,Ruby, right. It's introspective, which we've\Ntalked about a Dialogue: 0,0:13:37.02,0:13:39.04,Default,,0000,0000,0000,,little bit and we'll talk about more. And\Nit's Dialogue: 0,0:13:39.04,0:13:41.63,Default,,0000,0000,0000,,a dynamic and it's reflective, which means,\Nyou know, Dialogue: 0,0:13:41.63,0:13:43.00,Default,,0000,0000,0000,,we don't have to compile it and we can Dialogue: 0,0:13:43.00,0:13:46.97,Default,,0000,0000,0000,,change things on the fly in its runtime. Dialogue: 0,0:13:46.97,0:13:49.02,Default,,0000,0000,0000,,And I think we, we take advantage of these Dialogue: 0,0:13:49.02,0:13:51.72,Default,,0000,0000,0000,,things, you know, a lot in the code that Dialogue: 0,0:13:51.72,0:13:55.94,Default,,0000,0000,0000,,we write, whether we're doing metaprogramming\Nor monkeypatching or, Dialogue: 0,0:13:55.94,0:13:58.98,Default,,0000,0000,0000,,or anything like that. But we, we haven't\Nreally Dialogue: 0,0:13:58.98,0:14:01.84,Default,,0000,0000,0000,,taken advantage of, of these things in the\Ntools Dialogue: 0,0:14:01.84,0:14:04.88,Default,,0000,0000,0000,,and in our workflow yet. Dialogue: 0,0:14:04.88,0:14:08.90,Default,,0000,0000,0000,,So, when I talk about workflow and our problems Dialogue: 0,0:14:08.90,0:14:12.03,Default,,0000,0000,0000,,with our workflow, I see big problems with\Nthe Dialogue: 0,0:14:12.03,0:14:16.44,Default,,0000,0000,0000,,traditional workflow in, in Ruby development\Nthat I, that Dialogue: 0,0:14:16.44,0:14:18.61,Default,,0000,0000,0000,,I see. Right, I mean. By that I mean Dialogue: 0,0:14:18.61,0:14:21.18,Default,,0000,0000,0000,,we write some code in an editor. We save Dialogue: 0,0:14:21.18,0:14:24.06,Default,,0000,0000,0000,,it. We hop over to a terminal or we Dialogue: 0,0:14:24.06,0:14:26.39,Default,,0000,0000,0000,,pop over to a webpage and reload it and Dialogue: 0,0:14:26.39,0:14:28.60,Default,,0000,0000,0000,,run it to see if it worked and, if Dialogue: 0,0:14:28.60,0:14:31.08,Default,,0000,0000,0000,,it worked, we go back and continue on. If Dialogue: 0,0:14:31.08,0:14:33.31,Default,,0000,0000,0000,,it didn't, we fix it, we save. We go Dialogue: 0,0:14:33.31,0:14:38.86,Default,,0000,0000,0000,,back. We reload it, rerun it. Rinse, repeat,\Nright? Dialogue: 0,0:14:38.86,0:14:42.98,Default,,0000,0000,0000,,What, what are, what problems do I see with Dialogue: 0,0:14:42.98,0:14:46.94,Default,,0000,0000,0000,,this? First of all, it's disruptive and it's\Ndistracting Dialogue: 0,0:14:46.94,0:14:49.63,Default,,0000,0000,0000,,to keep switching back and forth, right. Some\Namount Dialogue: 0,0:14:49.63,0:14:53.81,Default,,0000,0000,0000,,of context-switching is always gonna be imminent,\Nright. But Dialogue: 0,0:14:53.81,0:14:56.41,Default,,0000,0000,0000,,any effort you can make to reduce that is Dialogue: 0,0:14:56.41,0:14:58.95,Default,,0000,0000,0000,,just gonna be a huge win for your flow, Dialogue: 0,0:14:58.95,0:15:02.30,Default,,0000,0000,0000,,you know, and your focus. Dialogue: 0,0:15:02.30,0:15:03.91,Default,,0000,0000,0000,,The second problem I see with that is it's Dialogue: 0,0:15:03.91,0:15:06.06,Default,,0000,0000,0000,,just guess work. We just write some code.\NOh, Dialogue: 0,0:15:06.06,0:15:08.43,Default,,0000,0000,0000,,yeah, I think it's gonna work. We save it. Dialogue: 0,0:15:08.43,0:15:10.52,Default,,0000,0000,0000,,We go over. We run it to see if Dialogue: 0,0:15:10.52,0:15:13.01,Default,,0000,0000,0000,,it works. We're just taking shots in the dark, Dialogue: 0,0:15:13.01,0:15:16.05,Default,,0000,0000,0000,,you know. You can ask this guy. Dialogue: 0,0:15:16.05,0:15:19.91,Default,,0000,0000,0000,,Taking shots with a flashlight is much more\Naccurate. Dialogue: 0,0:15:19.91,0:15:23.34,Default,,0000,0000,0000,,And recommended, apparently. So do that. Dialogue: 0,0:15:23.34,0:15:26.57,Default,,0000,0000,0000,,And, to me, it just seems backwards, right.\NWe, Dialogue: 0,0:15:26.57,0:15:31.30,Default,,0000,0000,0000,,we're like solidifying and codifying our code\Ninto our Dialogue: 0,0:15:31.30,0:15:33.94,Default,,0000,0000,0000,,code base just in an attempt to see if Dialogue: 0,0:15:33.94,0:15:37.58,Default,,0000,0000,0000,,it works. It should be the opposite. Our code Dialogue: 0,0:15:37.58,0:15:42.46,Default,,0000,0000,0000,,base, it should be the, the record of code Dialogue: 0,0:15:42.46,0:15:46.56,Default,,0000,0000,0000,,that we've, we've already validated, right.\NAnd I, I Dialogue: 0,0:15:46.56,0:15:49.94,Default,,0000,0000,0000,,mean these things are just kind of things\Nthat Dialogue: 0,0:15:49.94,0:15:52.97,Default,,0000,0000,0000,,we accept and, and we, we take for granted, Dialogue: 0,0:15:52.97,0:15:53.41,Default,,0000,0000,0000,,right. Dialogue: 0,0:15:53.41,0:15:57.04,Default,,0000,0000,0000,,But I mean, I think other languages have,\Nhave Dialogue: 0,0:15:57.04,0:16:01.41,Default,,0000,0000,0000,,been more effective and intentional about\Nintegrating this idea Dialogue: 0,0:16:01.41,0:16:06.05,Default,,0000,0000,0000,,of a runtime into the, their workflow, you\Nknow. Dialogue: 0,0:16:06.05,0:16:09.69,Default,,0000,0000,0000,,And blurring this line between static and\Nrunning code. Dialogue: 0,0:16:09.69,0:16:11.95,Default,,0000,0000,0000,,Clojure comes to mind, right. Dialogue: 0,0:16:11.95,0:16:14.76,Default,,0000,0000,0000,,But, we've talked about the awesome aspects\Nof Ruby, Dialogue: 0,0:16:14.76,0:16:17.81,Default,,0000,0000,0000,,and there's really nothing that restricts\Nor limits us Dialogue: 0,0:16:17.81,0:16:19.69,Default,,0000,0000,0000,,from doing the same, right. I mean, I think Dialogue: 0,0:16:19.69,0:16:23.52,Default,,0000,0000,0000,,the Ruby language is, the Ruby language enables\Nit, Dialogue: 0,0:16:23.52,0:16:26.25,Default,,0000,0000,0000,,you know. It's just that up to this point, Dialogue: 0,0:16:26.25,0:16:29.68,Default,,0000,0000,0000,,we really haven't had the tools to do so. Dialogue: 0,0:16:29.68,0:16:33.94,Default,,0000,0000,0000,,So, we talked about these workflow problems.\NHow does Dialogue: 0,0:16:33.94,0:16:38.76,Default,,0000,0000,0000,,Pry solve these workflow problems, right?\NI see that, Dialogue: 0,0:16:38.76,0:16:41.73,Default,,0000,0000,0000,,you know, the introspection and the documentation\Nand the Dialogue: 0,0:16:41.73,0:16:46.20,Default,,0000,0000,0000,,source code browsing, which we'll see in a\Nminute, Dialogue: 0,0:16:46.20,0:16:50.86,Default,,0000,0000,0000,,that's, that's baked into Pry, gives us ninety\Npercent Dialogue: 0,0:16:50.86,0:16:53.61,Default,,0000,0000,0000,,of the information that we need to write code Dialogue: 0,0:16:53.61,0:16:57.53,Default,,0000,0000,0000,,right now, you know, in most cases. Dialogue: 0,0:16:57.53,0:16:59.08,Default,,0000,0000,0000,,It has a runtime that you can throw your Dialogue: 0,0:16:59.08,0:17:01.57,Default,,0000,0000,0000,,code against and validate it and get feedback\Non Dialogue: 0,0:17:01.57,0:17:05.09,Default,,0000,0000,0000,,whether it, whether it works or not, immediately.\NAnd Dialogue: 0,0:17:05.09,0:17:07.28,Default,,0000,0000,0000,,it's smart about editing. You don't have to\Nthink Dialogue: 0,0:17:07.28,0:17:10.77,Default,,0000,0000,0000,,about what file you need to open. Pry usually Dialogue: 0,0:17:10.77,0:17:13.45,Default,,0000,0000,0000,,knows what file you want to edit and usually Dialogue: 0,0:17:13.45,0:17:15.80,Default,,0000,0000,0000,,knows exactly where you want to edit it. Which Dialogue: 0,0:17:15.80,0:17:18.30,Default,,0000,0000,0000,,is really nice. Dialogue: 0,0:17:18.30,0:17:25.30,Default,,0000,0000,0000,,So, when I talk about this idea of runtime Dialogue: 0,0:17:27.30,0:17:32.05,Default,,0000,0000,0000,,development, I'm really talking about being\Nimmersed in this, Dialogue: 0,0:17:32.05,0:17:36.51,Default,,0000,0000,0000,,in this environment that, you know, loves\Nus and Dialogue: 0,0:17:36.51,0:17:40.58,Default,,0000,0000,0000,,can give us feedback, and, and is alive, right. Dialogue: 0,0:17:40.58,0:17:42.22,Default,,0000,0000,0000,,So we want to spend the majority of our Dialogue: 0,0:17:42.22,0:17:45.56,Default,,0000,0000,0000,,development time there, and we want our editor\Nto Dialogue: 0,0:17:45.56,0:17:47.27,Default,,0000,0000,0000,,just be an after thought. And that's just\Na Dialogue: 0,0:17:47.27,0:17:49.71,Default,,0000,0000,0000,,place where we just push working code when\Nit's Dialogue: 0,0:17:49.71,0:17:51.19,Default,,0000,0000,0000,,done, right. Dialogue: 0,0:17:51.19,0:17:54.62,Default,,0000,0000,0000,,So, let me demo to you a little bit Dialogue: 0,0:17:54.62,0:18:01.62,Default,,0000,0000,0000,,about how I see that working, right. Dialogue: 0,0:18:02.58,0:18:08.04,Default,,0000,0000,0000,,So. Our mission is to write an empty class Dialogue: 0,0:18:08.04,0:18:11.20,Default,,0000,0000,0000,,definition, OK. This is just a script. No\NRails Dialogue: 0,0:18:11.20,0:18:15.16,Default,,0000,0000,0000,,involved here or anything. But given a class\Nlike Dialogue: 0,0:18:15.16,0:18:18.40,Default,,0000,0000,0000,,name like BowlingGame, we want to create a\Nfile, Dialogue: 0,0:18:18.40,0:18:22.19,Default,,0000,0000,0000,,bowling_game dot rb, and write a class definition\Nto Dialogue: 0,0:18:22.19,0:18:26.59,Default,,0000,0000,0000,,it, like class BowlingGame empty space end.\NRight, and Dialogue: 0,0:18:26.59,0:18:30.06,Default,,0000,0000,0000,,I've created a little skeleton here of, of\Nhow Dialogue: 0,0:18:30.06,0:18:31.87,Default,,0000,0000,0000,,I think that might work, right. Dialogue: 0,0:18:31.87,0:18:33.93,Default,,0000,0000,0000,,We're gonna, we're gonna read in a string\Nfrom Dialogue: 0,0:18:33.93,0:18:36.68,Default,,0000,0000,0000,,the command line, we're gonna pass that string\Ninto Dialogue: 0,0:18:36.68,0:18:39.64,Default,,0000,0000,0000,,a method called file_name_for_class and get\Na file name. Dialogue: 0,0:18:39.64,0:18:42.20,Default,,0000,0000,0000,,We're gonna pass that string into a method\Ncalled Dialogue: 0,0:18:42.20,0:18:45.80,Default,,0000,0000,0000,,class_definition for class and get a class\Ndefinition, and Dialogue: 0,0:18:45.80,0:18:48.07,Default,,0000,0000,0000,,then we're gonna create that class by writing\Nthat Dialogue: 0,0:18:48.07,0:18:52.74,Default,,0000,0000,0000,,class definition to that file. Right. Dialogue: 0,0:18:52.74,0:18:54.80,Default,,0000,0000,0000,,So let's step out here and let's just run Dialogue: 0,0:18:54.80,0:18:58.32,Default,,0000,0000,0000,,that. So, we get an expected error, right.\NWe Dialogue: 0,0:18:58.32,0:19:02.57,Default,,0000,0000,0000,,haven't implemented anything called file_name_for_class,\Nyet. So we could Dialogue: 0,0:19:02.57,0:19:04.88,Default,,0000,0000,0000,,jump into our editor and start coding and\Nall Dialogue: 0,0:19:04.88,0:19:10.22,Default,,0000,0000,0000,,that, but why don't we see what this is Dialogue: 0,0:19:10.22,0:19:13.13,Default,,0000,0000,0000,,like. Dialogue: 0,0:19:13.13,0:19:16.77,Default,,0000,0000,0000,,Why don't we use Pry rescue and leverage that Dialogue: 0,0:19:16.77,0:19:19.61,Default,,0000,0000,0000,,exception to drop us into a runtime and start Dialogue: 0,0:19:19.61,0:19:25.57,Default,,0000,0000,0000,,this runtime development process. So we do\Nthat. We Dialogue: 0,0:19:25.57,0:19:28.03,Default,,0000,0000,0000,,get the same error, but the difference is,\Nwe're Dialogue: 0,0:19:28.03,0:19:32.92,Default,,0000,0000,0000,,inside of a runtime now, OK. So, the first Dialogue: 0,0:19:32.92,0:19:35.20,Default,,0000,0000,0000,,problem is pretty easy. We know that we need Dialogue: 0,0:19:35.20,0:19:41.38,Default,,0000,0000,0000,,to define file_name_for_class. And we do so,\Nright. Dialogue: 0,0:19:41.38,0:19:44.37,Default,,0000,0000,0000,,The difference is in here, I'm gonna raise,\Nin Dialogue: 0,0:19:44.37,0:19:47.76,Default,,0000,0000,0000,,the implementation of this class, and drop\Nback out. Dialogue: 0,0:19:47.76,0:19:50.24,Default,,0000,0000,0000,,And I'll show you why. When we ask Pry Dialogue: 0,0:19:50.24,0:19:54.80,Default,,0000,0000,0000,,to try again, we get in here. We're right Dialogue: 0,0:19:54.80,0:19:58.03,Default,,0000,0000,0000,,where we need to be to define the implementa- Dialogue: 0,0:19:58.03,0:20:01.79,Default,,0000,0000,0000,,working implementation of this class. Although,\NI already know Dialogue: 0,0:20:01.79,0:20:06.09,Default,,0000,0000,0000,,that I have forgotten to pass in the BowlingGame Dialogue: 0,0:20:06.09,0:20:07.76,Default,,0000,0000,0000,,string, like I always do. Dialogue: 0,0:20:07.76,0:20:12.34,Default,,0000,0000,0000,,OK. Now we have everything we need. So we Dialogue: 0,0:20:12.34,0:20:15.13,Default,,0000,0000,0000,,have something like BowlingGame, right, and\Nwe're looking for Dialogue: 0,0:20:15.13,0:20:20.77,Default,,0000,0000,0000,,something like bowling_game dot rb, OK. So\NI'm just Dialogue: 0,0:20:20.77,0:20:24.97,Default,,0000,0000,0000,,gonna preview my favorite Pry command of all\Ntime Dialogue: 0,0:20:24.97,0:20:28.08,Default,,0000,0000,0000,,here. ls. Dialogue: 0,0:20:28.08,0:20:31.32,Default,,0000,0000,0000,,When I call ls, and give it the class Dialogue: 0,0:20:31.32,0:20:34.52,Default,,0000,0000,0000,,or the object I'm working with, I immediately\Nknow Dialogue: 0,0:20:34.52,0:20:37.40,Default,,0000,0000,0000,,I'm working with a string and I'm seeing all Dialogue: 0,0:20:37.40,0:20:39.89,Default,,0000,0000,0000,,of the methods that are available to me on Dialogue: 0,0:20:39.89,0:20:42.30,Default,,0000,0000,0000,,that string. And when I say all of the Dialogue: 0,0:20:42.30,0:20:45.24,Default,,0000,0000,0000,,methods, I don't mean all of them. Notice\Nthat Dialogue: 0,0:20:45.24,0:20:50.04,Default,,0000,0000,0000,,the object methods are not in here. And, you Dialogue: 0,0:20:50.04,0:20:53.68,Default,,0000,0000,0000,,know that if you've ever used IRB to get Dialogue: 0,0:20:53.68,0:20:56.68,Default,,0000,0000,0000,,the method, you always do, thing dot method\Nminus Dialogue: 0,0:20:56.68,0:20:59.66,Default,,0000,0000,0000,,object dot methods blah, blah, blah. Dialogue: 0,0:20:59.66,0:21:02.44,Default,,0000,0000,0000,,The, that's just noise, right, in most cases.\NSo Dialogue: 0,0:21:02.44,0:21:06.53,Default,,0000,0000,0000,,the default is just to leave that out. The Dialogue: 0,0:21:06.53,0:21:10.17,Default,,0000,0000,0000,,developers of Pry have thought of that, right.\NSo Dialogue: 0,0:21:10.17,0:21:15.57,Default,,0000,0000,0000,,we can try to class downcase, which gets us Dialogue: 0,0:21:15.57,0:21:18.25,Default,,0000,0000,0000,,so close, but yet so far away. We don't Dialogue: 0,0:21:18.25,0:21:20.82,Default,,0000,0000,0000,,really know where to put that underscore. Dialogue: 0,0:21:20.82,0:21:26.36,Default,,0000,0000,0000,,But, as Ruby devs, Rails devs, we know we Dialogue: 0,0:21:26.36,0:21:29.25,Default,,0000,0000,0000,,have things like ActiveSupport that can help\Nus out Dialogue: 0,0:21:29.25,0:21:34.57,Default,,0000,0000,0000,,with that. Dialogue: 0,0:21:34.57,0:21:37.36,Default,,0000,0000,0000,,So we include that, and now when we ls Dialogue: 0,0:21:37.36,0:21:39.98,Default,,0000,0000,0000,,our class, we've got some extra stuff in here, Dialogue: 0,0:21:39.98,0:21:43.65,Default,,0000,0000,0000,,right. Demodulalize, deconstantize, right.\NThat kind of stuff. And Dialogue: 0,0:21:43.65,0:21:46.39,Default,,0000,0000,0000,,if it, that's hard to see, we can just Dialogue: 0,0:21:46.39,0:21:51.40,Default,,0000,0000,0000,,ls ActiveSupport::Inflector itself and see\Nwhat's available to us Dialogue: 0,0:21:51.40,0:21:53.07,Default,,0000,0000,0000,,there, right. Dialogue: 0,0:21:53.07,0:21:55.53,Default,,0000,0000,0000,,So we need an und, we needed an underscore. Dialogue: 0,0:21:55.53,0:21:59.57,Default,,0000,0000,0000,,I see a method called underscore there. Tab\Ncompletion Dialogue: 0,0:21:59.57,0:22:02.45,Default,,0000,0000,0000,,is nice. All right. So now we're getting a Dialogue: 0,0:22:02.45,0:22:05.93,Default,,0000,0000,0000,,lot closer. All we need to do is stick Dialogue: 0,0:22:05.93,0:22:10.87,Default,,0000,0000,0000,,on our file exception, and I think we're done, Dialogue: 0,0:22:10.87,0:22:11.78,Default,,0000,0000,0000,,right. Dialogue: 0,0:22:11.78,0:22:16.35,Default,,0000,0000,0000,,So that, there's our filename. So let's copy\Nthat. Dialogue: 0,0:22:16.35,0:22:22.75,Default,,0000,0000,0000,,Let's drop back into our file. Right here,\Nexactly Dialogue: 0,0:22:22.75,0:22:26.32,Default,,0000,0000,0000,,where we need to put the implementation, let's\Nput Dialogue: 0,0:22:26.32,0:22:30.10,Default,,0000,0000,0000,,it in there. And let's save it and continue Dialogue: 0,0:22:30.10,0:22:32.81,Default,,0000,0000,0000,,on. OK, I know, I'm not gonna continue through Dialogue: 0,0:22:32.81,0:22:37.14,Default,,0000,0000,0000,,this whole thing, in the interest of time,\Nbut Dialogue: 0,0:22:37.14,0:22:42.15,Default,,0000,0000,0000,,I do want to, to implement this last method Dialogue: 0,0:22:42.15,0:22:44.07,Default,,0000,0000,0000,,inside of the create_class, so I can talk\Na Dialogue: 0,0:22:44.07,0:22:47.28,Default,,0000,0000,0000,,little bit more about what I love about introspection, Dialogue: 0,0:22:47.28,0:22:48.75,Default,,0000,0000,0000,,right. Dialogue: 0,0:22:48.75,0:22:50.80,Default,,0000,0000,0000,,Let's just reflect on what we did there, though, Dialogue: 0,0:22:50.80,0:22:54.07,Default,,0000,0000,0000,,with the workflow, OK. So we used, the, we Dialogue: 0,0:22:54.07,0:22:56.93,Default,,0000,0000,0000,,used pry-rescue to leverage the power, you\Nknow, to Dialogue: 0,0:22:56.93,0:23:00.05,Default,,0000,0000,0000,,leverage that exception, to pop us into a\Nruntime, Dialogue: 0,0:23:00.05,0:23:03.30,Default,,0000,0000,0000,,and we used the runtime of the debugger not Dialogue: 0,0:23:03.30,0:23:09.62,Default,,0000,0000,0000,,to fix code, but to drive our development\Nprocess, Dialogue: 0,0:23:09.62,0:23:12.02,Default,,0000,0000,0000,,right. Dialogue: 0,0:23:12.02,0:23:17.03,Default,,0000,0000,0000,,So. We're in here. We've raised inside of\Nour Dialogue: 0,0:23:17.03,0:23:20.85,Default,,0000,0000,0000,,create_class method. We try again. We've got\Nour file Dialogue: 0,0:23:20.85,0:23:27.85,Default,,0000,0000,0000,,name, and we've got our class definition.\NAnd we Dialogue: 0,0:23:28.86,0:23:32.38,Default,,0000,0000,0000,,have this file class, right. And, and I know Dialogue: 0,0:23:32.38,0:23:34.45,Default,,0000,0000,0000,,about this file class, and I know this is Dialogue: 0,0:23:34.45,0:23:36.99,Default,,0000,0000,0000,,exactly what I need to get the job done. Dialogue: 0,0:23:36.99,0:23:39.09,Default,,0000,0000,0000,,But, I mean, this is exactly what I, what Dialogue: 0,0:23:39.09,0:23:42.25,Default,,0000,0000,0000,,happened to me. I don't really remember exactly\Nwhat Dialogue: 0,0:23:42.25,0:23:44.37,Default,,0000,0000,0000,,I need to do here, OK. Dialogue: 0,0:23:44.37,0:23:47.67,Default,,0000,0000,0000,,So I can pop out to StackOverflow or I Dialogue: 0,0:23:47.67,0:23:50.78,Default,,0000,0000,0000,,can pop out to, to Ruby-docs or something\Nand Dialogue: 0,0:23:50.78,0:23:54.65,Default,,0000,0000,0000,,take a look. Or I can just ls file, Dialogue: 0,0:23:54.65,0:24:01.02,Default,,0000,0000,0000,,right here. And just take a minute to look Dialogue: 0,0:24:01.02,0:24:04.33,Default,,0000,0000,0000,,at this, and think about all of the low-level Dialogue: 0,0:24:04.33,0:24:07.64,Default,,0000,0000,0000,,Ruby instrospection acrobatics you would have\Nto go through Dialogue: 0,0:24:07.64,0:24:11.93,Default,,0000,0000,0000,,to get this brain dump of information right\Nhere. Dialogue: 0,0:24:11.93,0:24:13.94,Default,,0000,0000,0000,,We've got all of the methods that you can Dialogue: 0,0:24:13.94,0:24:16.48,Default,,0000,0000,0000,,call on instances of file. We've got all the Dialogue: 0,0:24:16.48,0:24:19.25,Default,,0000,0000,0000,,methods you can call on the file class. We've Dialogue: 0,0:24:19.25,0:24:22.69,Default,,0000,0000,0000,,got all of the methods that file inherits,\Nand, Dialogue: 0,0:24:22.69,0:24:25.65,Default,,0000,0000,0000,,from its superclass, and we know what that\Nsuperclass Dialogue: 0,0:24:25.65,0:24:26.95,Default,,0000,0000,0000,,is. IO. Dialogue: 0,0:24:26.95,0:24:29.07,Default,,0000,0000,0000,,We also know all the constants involved and\Nif Dialogue: 0,0:24:29.07,0:24:33.20,Default,,0000,0000,0000,,there was state involved in class or instance\Nvariables. Dialogue: 0,0:24:33.20,0:24:37.87,Default,,0000,0000,0000,,We would see that here as well. So, all Dialogue: 0,0:24:37.87,0:24:42.60,Default,,0000,0000,0000,,of a sudden, I'm informed about, about everything\NI Dialogue: 0,0:24:42.60,0:24:45.27,Default,,0000,0000,0000,,need to know about this class, and I have Dialogue: 0,0:24:45.27,0:24:47.77,Default,,0000,0000,0000,,a pretty good idea, just from a, from a Dialogue: 0,0:24:47.77,0:24:50.75,Default,,0000,0000,0000,,moment's notice, of how I can use it, or Dialogue: 0,0:24:50.75,0:24:54.38,Default,,0000,0000,0000,,what I can do to play around with it. Dialogue: 0,0:24:54.38,0:24:59.73,Default,,0000,0000,0000,,So let's. I see the right method. And I Dialogue: 0,0:24:59.73,0:25:02.39,Default,,0000,0000,0000,,don't really want to write anything or mess\Nwith Dialogue: 0,0:25:02.39,0:25:04.99,Default,,0000,0000,0000,,anything right now, so I'm just gonna look\Nat Dialogue: 0,0:25:04.99,0:25:09.15,Default,,0000,0000,0000,,the documentation for it. OK. It opens the\Nfile. Dialogue: 0,0:25:09.15,0:25:11.49,Default,,0000,0000,0000,,It optimally seeks to the given offset. Writes\Na Dialogue: 0,0:25:11.49,0:25:14.69,Default,,0000,0000,0000,,string, then returns the length written. Write\Nensures that Dialogue: 0,0:25:14.69,0:25:17.09,Default,,0000,0000,0000,,the files close before returning. This sounds\Nlike what Dialogue: 0,0:25:17.09,0:25:18.32,Default,,0000,0000,0000,,I want. Dialogue: 0,0:25:18.32,0:25:22.11,Default,,0000,0000,0000,,I page down. I see some examples there. Great. Dialogue: 0,0:25:22.11,0:25:26.67,Default,,0000,0000,0000,,I'm ready to go. Dialogue: 0,0:25:26.67,0:25:33.52,Default,,0000,0000,0000,,Alternatively, I can do the same and call\Nshow-source, Dialogue: 0,0:25:33.52,0:25:36.19,Default,,0000,0000,0000,,OK. Which isn't doing a lot for me here, Dialogue: 0,0:25:36.19,0:25:40.49,Default,,0000,0000,0000,,but when I'm in my, my own code base, Dialogue: 0,0:25:40.49,0:25:43.45,Default,,0000,0000,0000,,this is what I lean on more often, right. Dialogue: 0,0:25:43.45,0:25:50.41,Default,,0000,0000,0000,,So, let's get our bearings again. Dialogue: 0,0:25:50.41,0:25:57.41,Default,,0000,0000,0000,,And let's give it a try, right. File.write(file_name.class_definition).\NOK. Dialogue: 0,0:26:02.19,0:26:04.57,Default,,0000,0000,0000,,Something happened. It seemed to work, right.\NHow do Dialogue: 0,0:26:04.57,0:26:09.59,Default,,0000,0000,0000,,I know? Really easy to shell out in Pry. Dialogue: 0,0:26:09.59,0:26:13.24,Default,,0000,0000,0000,,You get really nice output. Exactly what you\Nwould Dialogue: 0,0:26:13.24,0:26:15.29,Default,,0000,0000,0000,,expect, which is, I can't say the same for Dialogue: 0,0:26:15.29,0:26:18.29,Default,,0000,0000,0000,,IRB in that, in that case. Dialogue: 0,0:26:18.29,0:26:20.56,Default,,0000,0000,0000,,I have this thing called bowling_game in there.\NLet's Dialogue: 0,0:26:20.56,0:26:27.52,Default,,0000,0000,0000,,take a look at it. That looks correct to Dialogue: 0,0:26:27.52,0:26:30.25,Default,,0000,0000,0000,,me. So let's just do that again. I'm gonna Dialogue: 0,0:26:30.25,0:26:34.38,Default,,0000,0000,0000,,copy the history again. And then I'm gonna\Nremove Dialogue: 0,0:26:34.38,0:26:39.03,Default,,0000,0000,0000,,bowling_game, just to make sure that my script\Nis Dialogue: 0,0:26:39.03,0:26:45.19,Default,,0000,0000,0000,,doing what it promises, right. Oops. Dialogue: 0,0:26:45.19,0:26:51.02,Default,,0000,0000,0000,,And it's not there anymore. So let's go back. Dialogue: 0,0:26:51.02,0:26:58.02,Default,,0000,0000,0000,,Let's put in that, let's put in that implementation. Dialogue: 0,0:27:02.32,0:27:06.15,Default,,0000,0000,0000,,And drop back in. Let's ask Pry to try Dialogue: 0,0:27:06.15,0:27:12.13,Default,,0000,0000,0000,,again. No more exceptions. Do we have our\Nbowling_game? Dialogue: 0,0:27:12.13,0:27:14.21,Default,,0000,0000,0000,,We do. Dialogue: 0,0:27:14.21,0:27:21.21,Default,,0000,0000,0000,,OK. So, what happened there, right? We used\Nthe Dialogue: 0,0:27:22.45,0:27:27.75,Default,,0000,0000,0000,,debugger and the runtime as, as, as a tool Dialogue: 0,0:27:27.75,0:27:32.38,Default,,0000,0000,0000,,for driving our development process and build\Nour implementation. Dialogue: 0,0:27:32.38,0:27:35.14,Default,,0000,0000,0000,,Not just to fix software, right. Dialogue: 0,0:27:35.14,0:27:38.34,Default,,0000,0000,0000,,We validated our implementation before codifying\Nit, and we Dialogue: 0,0:27:38.34,0:27:42.35,Default,,0000,0000,0000,,reversed this traditional workflow that I've\Ngot so many Dialogue: 0,0:27:42.35,0:27:47.01,Default,,0000,0000,0000,,problems with. We explored and we informed\Nourselves about Dialogue: 0,0:27:47.01,0:27:52.70,Default,,0000,0000,0000,,how to, how to use our classes without context Dialogue: 0,0:27:52.70,0:27:56.27,Default,,0000,0000,0000,,switching. Right, we stayed focused in one\Ntool. And Dialogue: 0,0:27:56.27,0:27:59.87,Default,,0000,0000,0000,,then we didn't have to reload our, our libraries Dialogue: 0,0:27:59.87,0:28:02.46,Default,,0000,0000,0000,,and our environment every time we wanted to\Nrun Dialogue: 0,0:28:02.46,0:28:05.92,Default,,0000,0000,0000,,code, so it was fast. Dialogue: 0,0:28:05.92,0:28:11.33,Default,,0000,0000,0000,,So, and, you know. We're in the testing track Dialogue: 0,0:28:11.33,0:28:13.37,Default,,0000,0000,0000,,here, so I should probably talk about testing\Na Dialogue: 0,0:28:13.37,0:28:17.99,Default,,0000,0000,0000,,little bit. And, that might have felt a little Dialogue: 0,0:28:17.99,0:28:19.85,Default,,0000,0000,0000,,bit like TDD to you. I mean, it does Dialogue: 0,0:28:19.85,0:28:26.34,Default,,0000,0000,0000,,to me, right. As, as practitioners of TDD,\Nyou Dialogue: 0,0:28:26.34,0:28:30.03,Default,,0000,0000,0000,,know, I may not, I'm, I'm, I love TDD. Dialogue: 0,0:28:30.03,0:28:35.03,Default,,0000,0000,0000,,I think most, many Rubyists do. Dialogue: 0,0:28:35.03,0:28:38.11,Default,,0000,0000,0000,,But I mean, what I love about it most Dialogue: 0,0:28:38.11,0:28:41.32,Default,,0000,0000,0000,,is it keeps me focused and, and, and, having Dialogue: 0,0:28:41.32,0:28:46.66,Default,,0000,0000,0000,,a test suite allows me to aggressively refactor\Nmy Dialogue: 0,0:28:46.66,0:28:48.24,Default,,0000,0000,0000,,code, you know, and have the confidence to\Ndo Dialogue: 0,0:28:48.24,0:28:50.61,Default,,0000,0000,0000,,that. You know, and I'd rather do that upfront Dialogue: 0,0:28:50.61,0:28:54.30,Default,,0000,0000,0000,,than after the fact, right. But, as practitioners\Nof Dialogue: 0,0:28:54.30,0:28:59.19,Default,,0000,0000,0000,,TDD, you know, we've learned to love failure,\Nyou Dialogue: 0,0:28:59.19,0:28:59.36,Default,,0000,0000,0000,,know. Dialogue: 0,0:28:59.36,0:29:02.23,Default,,0000,0000,0000,,TDD is all about making something fail, then\Nwriting Dialogue: 0,0:29:02.23,0:29:04.13,Default,,0000,0000,0000,,the code to make it pass. When we have Dialogue: 0,0:29:04.13,0:29:08.03,Default,,0000,0000,0000,,bugs, we want to exercise that exact piece\Nof Dialogue: 0,0:29:08.03,0:29:11.19,Default,,0000,0000,0000,,code that's giving us the error and get that Dialogue: 0,0:29:11.19,0:29:13.25,Default,,0000,0000,0000,,error, you know, before we then go, cause\Nwe Dialogue: 0,0:29:13.25,0:29:15.01,Default,,0000,0000,0000,,know we're about to do something cool and\Nfix Dialogue: 0,0:29:15.01,0:29:16.75,Default,,0000,0000,0000,,it, right. Dialogue: 0,0:29:16.75,0:29:21.73,Default,,0000,0000,0000,,So, we love to see red. And so a, Dialogue: 0,0:29:21.73,0:29:26.20,Default,,0000,0000,0000,,a practice that's, that's centered around\Nfailure is naturally Dialogue: 0,0:29:26.20,0:29:28.59,Default,,0000,0000,0000,,suited to a debugging tool, right. I mean,\Nthat's Dialogue: 0,0:29:28.59,0:29:32.52,Default,,0000,0000,0000,,what a debugging tool does. It's meant to\Nhandle Dialogue: 0,0:29:32.52,0:29:35.77,Default,,0000,0000,0000,,failures, catch failures, and then give you\Nthe tools Dialogue: 0,0:29:35.77,0:29:38.75,Default,,0000,0000,0000,,you need and enable you to fix them as Dialogue: 0,0:29:38.75,0:29:41.76,Default,,0000,0000,0000,,quickly as you can. And we've seen how awesome, Dialogue: 0,0:29:41.76,0:29:45.06,Default,,0000,0000,0000,,you know, a debugger Pry can be. Dialogue: 0,0:29:45.06,0:29:49.36,Default,,0000,0000,0000,,And, so, the promise of this talk is that Dialogue: 0,0:29:49.36,0:29:53.22,Default,,0000,0000,0000,,I'm going to, you know, deliver a, a, a Dialogue: 0,0:29:53.22,0:29:57.22,Default,,0000,0000,0000,,Pry-enabled TDD workflow. But before I do\Nthat, I Dialogue: 0,0:29:57.22,0:29:59.85,Default,,0000,0000,0000,,mean, I mentioned that, you know, I've had\Na, Dialogue: 0,0:29:59.85,0:30:04.34,Default,,0000,0000,0000,,kind of specific experience that made me a\Nbeliever Dialogue: 0,0:30:04.34,0:30:07.00,Default,,0000,0000,0000,,that this workflow even happens. I mean, I've\Nactually Dialogue: 0,0:30:07.00,0:30:10.35,Default,,0000,0000,0000,,done this before. I'm not creating this, right. Dialogue: 0,0:30:10.35,0:30:14.75,Default,,0000,0000,0000,,And, and that specific experience was this.\NDoes anybody Dialogue: 0,0:30:14.75,0:30:19.91,Default,,0000,0000,0000,,know what this is? Smalltalk. Yeah. This is\Na Dialogue: 0,0:30:19.91,0:30:24.99,Default,,0000,0000,0000,,screenshot of a Farrow Smalltalk IDE, right.\NAnd I Dialogue: 0,0:30:24.99,0:30:29.25,Default,,0000,0000,0000,,spent about a year or so in the 2000s Dialogue: 0,0:30:29.25,0:30:32.01,Default,,0000,0000,0000,,writing a web application in the C-side framework\Nin Dialogue: 0,0:30:32.01,0:30:35.20,Default,,0000,0000,0000,,Smalltalk for a company in New York City with, Dialogue: 0,0:30:35.20,0:30:37.24,Default,,0000,0000,0000,,with a team of guys. Dialogue: 0,0:30:37.24,0:30:41.74,Default,,0000,0000,0000,,And, really delving into object-oriented programming,\Nand learning so Dialogue: 0,0:30:41.74,0:30:44.83,Default,,0000,0000,0000,,much about it, I really learned to love this, Dialogue: 0,0:30:44.83,0:30:48.91,Default,,0000,0000,0000,,right. But what first, what first struck me\Nwhen Dialogue: 0,0:30:48.91,0:30:52.25,Default,,0000,0000,0000,,I saw Pry and I saw the ls command Dialogue: 0,0:30:52.25,0:30:57.06,Default,,0000,0000,0000,,was it reminded me of this, right. Right here, Dialogue: 0,0:30:57.06,0:31:00.58,Default,,0000,0000,0000,,we are looking at a ZnClient class in a Dialogue: 0,0:31:00.58,0:31:05.16,Default,,0000,0000,0000,,Zinc HTTP package. We see the class definition\Nright Dialogue: 0,0:31:05.16,0:31:07.73,Default,,0000,0000,0000,,there at the bottom, with all of the instance Dialogue: 0,0:31:07.73,0:31:11.51,Default,,0000,0000,0000,,variables that this class makes use of listed\Nout. Dialogue: 0,0:31:11.51,0:31:13.93,Default,,0000,0000,0000,,On the right hand side, we see all the Dialogue: 0,0:31:13.93,0:31:17.26,Default,,0000,0000,0000,,methods that we can call on this, on a, Dialogue: 0,0:31:17.26,0:31:19.53,Default,,0000,0000,0000,,on an instance of class, and we can click Dialogue: 0,0:31:19.53,0:31:22.86,Default,,0000,0000,0000,,on any of those to see the source code Dialogue: 0,0:31:22.86,0:31:27.09,Default,,0000,0000,0000,,of that method. I mean, that's all, that's\Nall Dialogue: 0,0:31:27.09,0:31:31.34,Default,,0000,0000,0000,,you need, as far as I'm concerned. I mean, Dialogue: 0,0:31:31.34,0:31:34.76,Default,,0000,0000,0000,,that gets you ninety percent of the way there Dialogue: 0,0:31:34.76,0:31:38.75,Default,,0000,0000,0000,,almost every, like, almost every time, right. Dialogue: 0,0:31:38.75,0:31:43.40,Default,,0000,0000,0000,,So, I wanted to, I wanted to demo, like Dialogue: 0,0:31:43.40,0:31:46.04,Default,,0000,0000,0000,,a, a Smalltalk TDD workflow, cause that's\Nthe other Dialogue: 0,0:31:46.04,0:31:49.58,Default,,0000,0000,0000,,really cool thing about Smalltalk and different\Nthing about Dialogue: 0,0:31:49.58,0:31:52.96,Default,,0000,0000,0000,,Smalltalk is that it really, like, enables\Nthis awesome Dialogue: 0,0:31:52.96,0:31:55.27,Default,,0000,0000,0000,,TDD workflow. And I don't think I'm gonna\Nhave Dialogue: 0,0:31:55.27,0:31:58.11,Default,,0000,0000,0000,,the time to do that unfortunately. Dialogue: 0,0:31:58.11,0:32:04.87,Default,,0000,0000,0000,,But the TL;DR is this, basically. OK. So if Dialogue: 0,0:32:04.87,0:32:07.97,Default,,0000,0000,0000,,I write a test, and I try to exercise Dialogue: 0,0:32:07.97,0:32:14.02,Default,,0000,0000,0000,,a class that doesn't exist, like BowlingGame\Nhere, Smalltalk's, Dialogue: 0,0:32:14.02,0:32:17.63,Default,,0000,0000,0000,,when I save this, Smalltalk's gonna say, that\Ndoesn't Dialogue: 0,0:32:17.63,0:32:19.28,Default,,0000,0000,0000,,exist. Do you wanna, what do you want to Dialogue: 0,0:32:19.28,0:32:20.46,Default,,0000,0000,0000,,do? Dialogue: 0,0:32:20.46,0:32:23.99,Default,,0000,0000,0000,,And the first option there is define new class. Dialogue: 0,0:32:23.99,0:32:27.85,Default,,0000,0000,0000,,You just click it and it does it, right. Dialogue: 0,0:32:27.85,0:32:30.41,Default,,0000,0000,0000,,When I try to call a method on that Dialogue: 0,0:32:30.41,0:32:36.24,Default,,0000,0000,0000,,class that doesn't exist, Smalltalk asks me\Nif I Dialogue: 0,0:32:36.24,0:32:39.99,Default,,0000,0000,0000,,want to implement that method, and when I\Nsay Dialogue: 0,0:32:39.99,0:32:44.25,Default,,0000,0000,0000,,yes, it drops me into a debugger, right. A Dialogue: 0,0:32:44.25,0:32:47.63,Default,,0000,0000,0000,,runtime, where I have everything available\NI need to Dialogue: 0,0:32:47.63,0:32:50.10,Default,,0000,0000,0000,,create the implementation of that class, and\NI can Dialogue: 0,0:32:50.10,0:32:52.65,Default,,0000,0000,0000,,expect all the things I need to do so. Dialogue: 0,0:32:52.65,0:32:56.34,Default,,0000,0000,0000,,Right, I'm not in a static code editor here. Dialogue: 0,0:32:56.34,0:33:00.97,Default,,0000,0000,0000,,This is like, living system, right. So I can Dialogue: 0,0:33:00.97,0:33:03.83,Default,,0000,0000,0000,,do so. Just want to return zero. And when Dialogue: 0,0:33:03.83,0:33:08.98,Default,,0000,0000,0000,,I save, my tests pass. So that's. That's,\Nthat's Dialogue: 0,0:33:08.98,0:33:13.01,Default,,0000,0000,0000,,the idea, right. And, and it, it's small,\Nbut, Dialogue: 0,0:33:13.01,0:33:17.19,Default,,0000,0000,0000,,you know, small changes in your user interface,\Nyou Dialogue: 0,0:33:17.19,0:33:20.63,Default,,0000,0000,0000,,know, can really turn, like a daunting experience\Ninto Dialogue: 0,0:33:20.63,0:33:23.29,Default,,0000,0000,0000,,a really motivating flow, right. Dialogue: 0,0:33:23.29,0:33:25.87,Default,,0000,0000,0000,,It doesn't take much. Dialogue: 0,0:33:25.87,0:33:29.65,Default,,0000,0000,0000,,So, when I talk about, you know, this power Dialogue: 0,0:33:29.65,0:33:31.83,Default,,0000,0000,0000,,of Pry and, and we've talked about some of Dialogue: 0,0:33:31.83,0:33:35.98,Default,,0000,0000,0000,,the plugins and how powerful they are and\Nhow, Dialogue: 0,0:33:35.98,0:33:39.63,Default,,0000,0000,0000,,you know, Pry is so easy to extend, you Dialogue: 0,0:33:39.63,0:33:43.68,Default,,0000,0000,0000,,know, even I can do it. And, and so, Dialogue: 0,0:33:43.68,0:33:46.35,Default,,0000,0000,0000,,I've kind of gotten the ball rolling. Dialogue: 0,0:33:46.35,0:33:51.77,Default,,0000,0000,0000,,I pushed a little code up to GitHub. It Dialogue: 0,0:33:51.77,0:33:55.27,Default,,0000,0000,0000,,defines a new command called define-it in\NPry. Right Dialogue: 0,0:33:55.27,0:33:57.86,Default,,0000,0000,0000,,now, it's just a PryRC, and you can define Dialogue: 0,0:33:57.86,0:34:00.00,Default,,0000,0000,0000,,Pry commands in your PryRC or you can do Dialogue: 0,0:34:00.00,0:34:03.47,Default,,0000,0000,0000,,gems or whatever, and that's, that's where\NI want Dialogue: 0,0:34:03.47,0:34:05.36,Default,,0000,0000,0000,,to move it. Dialogue: 0,0:34:05.36,0:34:09.12,Default,,0000,0000,0000,,But, this is my attempt to kind of get Dialogue: 0,0:34:09.12,0:34:16.12,Default,,0000,0000,0000,,this workflow going in, in Ruby, right. So,\Nall Dialogue: 0,0:34:22.28,0:34:27.59,Default,,0000,0000,0000,,right. So here it is. Here's my PryRC. I'm Dialogue: 0,0:34:27.59,0:34:33.43,Default,,0000,0000,0000,,creating a command called define-it, and then\NI'm implementing Dialogue: 0,0:34:33.43,0:34:38.25,Default,,0000,0000,0000,,- every Pry command implements this method\Ncalled process, Dialogue: 0,0:34:38.25,0:34:40.29,Default,,0000,0000,0000,,and that is what is going to happen when Dialogue: 0,0:34:40.29,0:34:43.17,Default,,0000,0000,0000,,you call the command from within the Pry REPL, Dialogue: 0,0:34:43.17,0:34:43.95,Default,,0000,0000,0000,,right. Dialogue: 0,0:34:43.95,0:34:45.98,Default,,0000,0000,0000,,And so I'm kind of using this idea that Dialogue: 0,0:34:45.98,0:34:50.18,Default,,0000,0000,0000,,we demoed in the last demo of, when I Dialogue: 0,0:34:50.18,0:34:52.94,Default,,0000,0000,0000,,hit a name error, I just want to automatically Dialogue: 0,0:34:52.94,0:34:57.51,Default,,0000,0000,0000,,generate an empty class definition and move\Non. What Dialogue: 0,0:34:57.51,0:34:59.00,Default,,0000,0000,0000,,it will also do is when I hit a Dialogue: 0,0:34:59.00,0:35:05.23,Default,,0000,0000,0000,,NoMethodError, it's gonna generate an empty\Nmethod definition and Dialogue: 0,0:35:05.23,0:35:07.21,Default,,0000,0000,0000,,put you right in there where you need to Dialogue: 0,0:35:07.21,0:35:11.99,Default,,0000,0000,0000,,be to implement it, right. Dialogue: 0,0:35:11.99,0:35:18.99,Default,,0000,0000,0000,,So let's take a look. So, once again. Oh, Dialogue: 0,0:35:19.08,0:35:23.49,Default,,0000,0000,0000,,let me just show you this real quick, though. Dialogue: 0,0:35:23.49,0:35:25.77,Default,,0000,0000,0000,,So here is a spec and a set of Dialogue: 0,0:35:25.77,0:35:29.79,Default,,0000,0000,0000,,tests that exercise this BowlingGame class,\Nright. The first Dialogue: 0,0:35:29.79,0:35:34.56,Default,,0000,0000,0000,,test just verifies that BowlingGame is a thing.\NThe Dialogue: 0,0:35:34.56,0:35:37.71,Default,,0000,0000,0000,,second test says if I ask a new BowlingGame Dialogue: 0,0:35:37.71,0:35:40.84,Default,,0000,0000,0000,,for its score, it should return zero. The\Nthird Dialogue: 0,0:35:40.84,0:35:43.43,Default,,0000,0000,0000,,test says, if I bowl a four then the Dialogue: 0,0:35:43.43,0:35:46.29,Default,,0000,0000,0000,,game's score should reflect that. Dialogue: 0,0:35:46.29,0:35:50.58,Default,,0000,0000,0000,,And the last test says, if I bowl twice, Dialogue: 0,0:35:50.58,0:35:54.44,Default,,0000,0000,0000,,you know, the, the score should reflect that,\Nthat Dialogue: 0,0:35:54.44,0:36:01.44,Default,,0000,0000,0000,,sum. So, when I run rSpec under pry-rescue,\Npry-rescue, Dialogue: 0,0:36:07.12,0:36:10.64,Default,,0000,0000,0000,,you know, it does different things in different\Ncontexts, Dialogue: 0,0:36:10.64,0:36:14.95,Default,,0000,0000,0000,,right. So just like before, pry-rescue's gonna\Nbreak on Dialogue: 0,0:36:14.95,0:36:19.70,Default,,0000,0000,0000,,unhandled exceptions, just like it always\Nhas done, but Dialogue: 0,0:36:19.70,0:36:23.04,Default,,0000,0000,0000,,in the context of rSpec, it's also gonna break Dialogue: 0,0:36:23.04,0:36:25.58,Default,,0000,0000,0000,,on assertion failures, all right. So you can\Npoke Dialogue: 0,0:36:25.58,0:36:28.04,Default,,0000,0000,0000,,around and get those fixed. Dialogue: 0,0:36:28.04,0:36:34.21,Default,,0000,0000,0000,,So, here we are. We. We've got our first Dialogue: 0,0:36:34.21,0:36:41.21,Default,,0000,0000,0000,,exception, right. It's the name error. Uninitialized\Nconstant BowlingGame. Dialogue: 0,0:36:41.88,0:36:45.67,Default,,0000,0000,0000,,So let's define it. Dialogue: 0,0:36:45.67,0:36:52.52,Default,,0000,0000,0000,,All right. Didn't see it, but it did it. Dialogue: 0,0:36:52.52,0:36:56.29,Default,,0000,0000,0000,,Next. Believe me. Dialogue: 0,0:36:56.29,0:37:01.45,Default,,0000,0000,0000,,All right. So next. Next, we've got our next Dialogue: 0,0:37:01.45,0:37:04.72,Default,,0000,0000,0000,,exception here right. Undefined method 'score'\Nfor BowlingGame. Our Dialogue: 0,0:37:04.72,0:37:10.50,Default,,0000,0000,0000,,NoMethodError. So let's define-it. You guys\Ndidn't believe me, Dialogue: 0,0:37:10.50,0:37:13.71,Default,,0000,0000,0000,,but there it is. All right. There we go. Dialogue: 0,0:37:13.71,0:37:18.37,Default,,0000,0000,0000,,We're in our empty method. Let's TDD, right.\NWe Dialogue: 0,0:37:18.37,0:37:20.35,Default,,0000,0000,0000,,just need to make the test pass so we Dialogue: 0,0:37:20.35,0:37:23.65,Default,,0000,0000,0000,,return zero out of there. Ask pry-rescue to\Ntry Dialogue: 0,0:37:23.65,0:37:28.73,Default,,0000,0000,0000,,again. We got another exception here. NoMethodError:\Nundefined method Dialogue: 0,0:37:28.73,0:37:30.21,Default,,0000,0000,0000,,'bowl' for BowlingGame. Dialogue: 0,0:37:30.21,0:37:34.18,Default,,0000,0000,0000,,So, let's define-it. Now I feel like we're\Ngonna Dialogue: 0,0:37:34.18,0:37:37.55,Default,,0000,0000,0000,,need to keep track of a little state, so Dialogue: 0,0:37:37.55,0:37:44.55,Default,,0000,0000,0000,,let's. We want to make that the fixnum. Dialogue: 0,0:37:46.45,0:37:49.86,Default,,0000,0000,0000,,We want to return @score out of here now, Dialogue: 0,0:37:49.86,0:37:56.46,Default,,0000,0000,0000,,instead. And let's initialize @score to be\Nzero when Dialogue: 0,0:37:56.46,0:38:02.79,Default,,0000,0000,0000,,you create a new BowlingGame. Let's save that\Nand Dialogue: 0,0:38:02.79,0:38:03.83,Default,,0000,0000,0000,,let's try again. Dialogue: 0,0:38:03.83,0:38:08.09,Default,,0000,0000,0000,,All right. That worked. We're in our last\Ntest Dialogue: 0,0:38:08.09,0:38:11.78,Default,,0000,0000,0000,,here, and we've hit our first assertion error,\Nright. Dialogue: 0,0:38:11.78,0:38:14.65,Default,,0000,0000,0000,,It expected nine and it got five, cause we're Dialogue: 0,0:38:14.65,0:38:18.57,Default,,0000,0000,0000,,not doing any of the, the totaling yet. So Dialogue: 0,0:38:18.57,0:38:23.54,Default,,0000,0000,0000,,let's, this is another way you can call edit. Dialogue: 0,0:38:23.54,0:38:27.13,Default,,0000,0000,0000,,You can just ask it to edit the class, Dialogue: 0,0:38:27.13,0:38:30.69,Default,,0000,0000,0000,,and it'll know what file to drop into. So Dialogue: 0,0:38:30.69,0:38:32.28,Default,,0000,0000,0000,,I feel like we're gonna want to keep track Dialogue: 0,0:38:32.28,0:38:35.42,Default,,0000,0000,0000,,of our scores now. So let's just push those Dialogue: 0,0:38:35.42,0:38:40.64,Default,,0000,0000,0000,,fixnums on a scores array. Let's get our score Dialogue: 0,0:38:40.64,0:38:44.48,Default,,0000,0000,0000,,by reducing those values. That's how you keep\Nscore Dialogue: 0,0:38:44.48,0:38:47.22,Default,,0000,0000,0000,,in bowling, right. You just add everything\Nup. All Dialogue: 0,0:38:47.22,0:38:48.57,Default,,0000,0000,0000,,right. Cool. Dialogue: 0,0:38:48.57,0:38:53.28,Default,,0000,0000,0000,,And let's, let's initialize it with an array\Nwith Dialogue: 0,0:38:53.28,0:38:58.89,Default,,0000,0000,0000,,initial value of zero as well. Let's try again. Dialogue: 0,0:38:58.89,0:39:05.89,Default,,0000,0000,0000,,Something's wrong there. There it is. Dialogue: 0,0:39:07.08,0:39:14.08,Default,,0000,0000,0000,,All right. Four examples, zero failures. rSpec\Nthought we Dialogue: 0,0:39:14.84,0:39:21.84,Default,,0000,0000,0000,,didn't fail at all, you know. It's pretty\Ncool. Dialogue: 0,0:39:25.34,0:39:32.34,Default,,0000,0000,0000,,So. So what happened there? All right. I mean, Dialogue: 0,0:39:34.08,0:39:40.13,Default,,0000,0000,0000,,basically, you know, we. We, again, we used\NPry Dialogue: 0,0:39:40.13,0:39:44.58,Default,,0000,0000,0000,,to drive our development process. We used\Nour own Dialogue: 0,0:39:44.58,0:39:47.70,Default,,0000,0000,0000,,Pry plugin there to kind of make that a Dialogue: 0,0:39:47.70,0:39:52.39,Default,,0000,0000,0000,,little bit easier, and within one runtime,\Nwe fixed Dialogue: 0,0:39:52.39,0:39:56.89,Default,,0000,0000,0000,,all of our assertions, exercised our class\Nand implemented Dialogue: 0,0:39:56.89,0:39:58.59,Default,,0000,0000,0000,,the whole solution, right. Dialogue: 0,0:39:58.59,0:40:01.73,Default,,0000,0000,0000,,No reloading, no nothing like that. Dialogue: 0,0:40:01.73,0:40:08.73,Default,,0000,0000,0000,,So, in conclusion, embrace your runtime and\Nall things. Dialogue: 0,0:40:10.15,0:40:14.57,Default,,0000,0000,0000,,Don't read the effing manual. Dialogue: 0,0:40:14.57,0:40:20.92,Default,,0000,0000,0000,,Use a kickass flashlight. Dialogue: 0,0:40:20.92,0:40:24.34,Default,,0000,0000,0000,,If you're fixing software, use a debugger.\NIf you're Dialogue: 0,0:40:24.34,0:40:27.85,Default,,0000,0000,0000,,building software, use a debugger. And when\Nyou use Dialogue: 0,0:40:27.85,0:40:30.37,Default,,0000,0000,0000,,a debugger, use Pry. Dialogue: 0,0:40:30.37,0:40:32.37,Default,,0000,0000,0000,,Thank you very much.