330: Bikeshed Baby
The Bike Shed - A podcast by thoughtbot - Tuesdays
Categories:
BIG NEWS! Steph's expecting a baby boy! πΌπ Aaaand unfortunately, the rest of the show isn't nearly as exciting. Chris talks about admin pagination using Pagy, and Steph wants to delete some code and is nervous that she's going to break something. They answer a listener question from Slash, who asks, "What are the first keyboard shortcuts you teach junior devs?" This episode is brought to you by ScoutAPM. Give Scout a try for free today and Scout will donate $5 to the open source project of your choice when you deploy. Pagy Upcase advanced queries fzf Become a Sponsor of The Bike Shed! Transcript: STEPH: Let's go. Oh man, now all I can think of is the...but what's his face? The quarterback for The Patriots formerly. Oh my God, I can't remember his name. CHRIS: Tom Brady? STEPH: [laughs] Thank you. Tom Brady. I wanted to say Brad Pitt, but I'm like, that's not right. [laughs] CHRIS: See, I thought of the musical...well, I think it's a musical, Encanto. Have you watched Encanto? STEPH: Oh, I love Encanto. CHRIS: It's so good. STEPH: We Don't Talk About Bruno, no, no, no! CHRIS: We Don't Talk About Bruno but...it was my wedding day. STEPH: But also Luisa Song, that's actually a good one too. CHRIS: Luisa Song that we have now listened to the soundtrack a lot of times, and we've only watched the movie twice, once ourselves and then once with our niece and nephew. That is the order it happened in as well, just to be clear. [laughs] But yeah, it's good, lots of slaptitude to all the music and the overall movie and really just fantastic work. Lin-Manuel Miranda does good stuff. STEPH: Super good. I have to bring back closure to my Tom Brady confusion, though. CHRIS: Yeah, what was that? [laughs] STEPH: [laughs] Now when I say the let's go, I think it was the Hertz commercial where he said, "Let's go," and he was impatient. I don't know if you've seen it. But marketing works, and now it's in my brain, and I hate it. [laughs] Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Steph Viccari. CHRIS: And I'm Chris Toomey. STEPH: And together, we're here to share a bit of what we've learned along the way. Hey, Chris, what's new in your world? CHRIS: What's new in my world? I got some stuff, some tech things, and whatnot to ramble about, but frankly, much less interesting. What's new in your world, Steph? STEPH: I do have some news, and I have some exciting news. So Tim and I, we are expecting our first child, hooray! CHRIS: Yay! STEPH: [laughs] We found out over Christmas or around the holiday. So depending on when this airs, but I'm around 14-15 weeks long. And it's tough. Growing a little human is tough. And it's been quite an adventure. And thankfully, I've got some friends to lean on and talk to through the process. But yes, that's my big news. We're going to have our first child. And oh, we also found out recently the sex of the child, and we found out we're going to have a baby boy, which is very exciting. CHRIS: Well, that is so wonderful. I'm so happy for you. And on behalf of the entire Bike Shed audience, I think it's very easy for me to carry forward their best wishes. But this is absolutely wonderful. And I hope you didn't mind me redirecting the questioning right back at you at the start of this episode because this seemed more important than any tech nonsense I'm going to ramble about. STEPH: Well, and you've been in the know for quite some time. And so we've been keeping it hush-hush until it felt like the right time to share. And this feels like the right time to go ahead and share. So there might be some interesting episodes up ahead where I get to complain and talk about this some more on the mic [laughs] since I have been keeping it quiet, but now I can talk about it more publicly. CHRIS: Absolutely. I think this has been decidedly missing from The Bike Shed content in the six, seven years that this show's been going. So yeah, let's sell some truths. STEPH: Bike Shed baby, that'll be one of our topics for sure. [laughs] But yeah, that's some of my big, exciting news. I'm going to kick it back to you since you were so kind to let me lead. What's going on in your world? CHRIS: Back to me. I'm going to talk about admin pagination. So it really felt wrong to me that I'll be like, let me talk about pagination for a while. Also, what's up? So that said, now that we have shared the wonderful, exciting news, I can talk about the mundane realities of pagination. So yeah, I'm going to try and tell this one in a story to make it more interesting. So we have an admin page. It lists out the users of our application, as is so often the case. And we hit that wonderful place where the page became wildly unreliable because we had so many people sign up for the application; yay! Very exciting. I feel like it's a meaningful milestone to get to where we're like, oh yeah, I guess we have to add pagination to the admin. Unfortunately, I picked this one up as, just like, this should be a quick, easy thing. This will be fun. Coding, you know, I've gone back and forth on individual weeks where I have space in my schedule for coding, and then sometimes I find it difficult. And I'm trying to not pick up larger, more critical pieces of work. But this one seemed like a perfect little pickup. I'm just going to grab this, and I'm just going to quickly bang out some pagination, and the admin team will be so excited. Everything's going to be wonderful. Smash cut to that did not work out so great. So I tried to introduce pagination using the Pagy gem, which I had not used before, but it's good. It seemed useful. And in particular, I'd seen an example from another Inertia Rails application that was using Pagy, and I was like, oh, cool, I'll just crib what they're doing. Because basically, we need to both get the data for the users and then serialize down the pagination data, the metadata about pagination. What page are we on? How many pages are there? Is there a next page? Is there a previous page? All of that kind of stuff. We need to serialize that down to the front end, and then use that to build a little pagination UI. So like, they're using Pagy, and it does seem to do a good job of yielding both of those pieces of data to me, so both the recordset that it's paginated down to and the metadata about pagination. But unfortunately, when I first tried to use it, I ran into a wall where our user page basically just lists out the user. At the top, it has a little search bar, so you can type in name, or email, or ID. And then there's a little drop-down for the account status. What's the status of this user? So we can filter down to active accounts or onboarding accounts or that sort of stuff. Running the search, everything went fine. When I went to filter down, suddenly it broke, and that was sad. So I went and chased it down. Pagy was throwing an error that it couldn't work with the collection that it was working with. And the reason was our admin user query object was iterating over the objects in Ruby land to do the filtering, which was very sad. So it turned out that the admin user query object, when it needed to do that filtering based on status, it was actually iterating through all the records and filtering them out using select or reject, whichever side. I forget which way it was implemented. But either way, it was iterating through the entire collection. And so, Pagy, like most pagination things, tries to use offset-based pagination and database queries. So OFFSET LIMIT, that combination of things allows you to move through a recordset pretty easily. This is setting aside the idea of cursor-based pagination, which I've never fully understood or implemented, but let's just stick with OFFSET and LIMIT because they're going to get us what we need in this particular case. But by virtue of the fact that we're actually working with that recordset, turning it into an array, getting all of the records, it was less efficient than it needed to be. But it also meant that we didn't have an ActiveRecord relation that we could do this with. And so then began the adventure of like, okay, this should be easy. I'll just turn it into a database query, except the account status was implemented as a method spread across a few models that looked at a value and then returned something, and that's why it was doing this in-memory filtering. But this is a classic case of I just want to add pagination. It will be super easy. Never mind, let me undertake a fundamental refactoring to the entire application and unify the idea of account status across user and the background object and this other object. And then once that giant refactoring PR lands and I deal with the fallout of how this broke analytics and other pages in the app...it was a good thing. It was necessary. That was a mess, and we knew that. Fixing that was a good thing to do not just for the pagination but for actually unifying all of those ideas. Then once I landed that refactoring PR, oh, it's so easy to put in the pagination. [laughs] Just like, oh yeah, just paginate. That'll be great. STEPH: You got back to the happy place of where it was easy again. CHRIS: Took me like a week and a half to do the refactoring PR, though, partly because I was in and out on it. I couldn't give it my full focus. But there was definitely a morning where I was like, oh yeah, I'm going to add pagination to the admin UI. And the admin team was like, that's fantastic. We're very excited. A week and a half later, I was like, I'm sorry, I finally got to it, though. It's really good, though, right? STEPH: I changed a bunch of things that you can't tell that I changed, but I promise it's a lot better. So now I can actually implement the change that you want to see. Well, I'm glad you walked away with a win because I've definitely been in the space where I have entered the refactor world and walked away with an L and realized that it's something that either wasn't worth tackling at the time or was just too challenging. CHRIS: Oh yeah, I've definitely had that. And I think if it were a different shape of refactoring that were necessary to support this, I probably would have backed away, but because it was fundamental data model cleanup that needed to happen under the hood, I was like, that feels right. We should be doing this anyway. I'm also a big believer in dealing with ActiveRecord relations. So for anyone that's not familiar with the way ActiveRecord works, query evaluation is lazy. And so you can say user.where first name, blah. And that returns an unevaluated query, the idea of a query in the future, AKA an ActiveRecord relation. And you can keep chaining on to that and building new relation. So you can say .where this thing and then pass that return object to something else, which then chains on another thing .joins to something else and then filter on an aspect of that. But again, we're not going to evaluate the query until we need it, typically until we iterate through the records that are part of it. And so, this is one of those things that I have, over time, slowly worked on and refined. And this is a skill area that I continually find value in investing in. Again, I'll reference the wonderful Advanced ActiveRecord Querying course on Upcase that Joe Ferris hosted, and then I got to be a participant in, and still, I'm learning bits from that one years later. But the idea of really understanding what we can do with the database layer and then how we can reflect that in the ActiveRecord query syntax. And then ideally, I have this motto in my head, which is just stay in relation land for as long as you possibly can. The minute you type .to_a to coerce it into an array or something like that, you have perhaps solved the immediate problem that you have, but at what cost? I ask, at what cost? The answer is a very big cost. You can't do other cool stuff after that. STEPH: I'm intrigued how you refactored it because when you're talking about having the status, in my mind, I was presuming that it was a database column on one of the models. But then you'd mentioned it's not and that it's scattered across. So how did you refactor that and so then you could stay in relation land? CHRIS: Primarily, we pushed the logic. So, unfortunately, it was spread across a few different objects. That was one complicated thing. So the idea of a status was spread across a few different spots actually in a few different models. So one thing was just to unify them all into one enum on the canonical record that should really own this idea. And then, really, it was to push it down into the database. So that was part of the work. We also recognized that we had done not a great job with the implementation of the enum and with the naming of the key and the value in that enum in terms of how it was implemented in Rails. So there was a bunch of confusion. There was basically just a bunch of places where we had been less intentional than we probably should have. So mostly, it was just pushing all of that together and down into the database. And then where the status changes at any point in the application, we're just updating that column in the database, and then everything else can just happily work with that value. STEPH: Got it. Yeah, that sounds great. Thanks. CHRIS: You're welcome. But yeah, it really was a case of like that PR to refactor was a bit of a slog, if we're being honest. It was not fun. I was scared I was going to break stuff. I had to be very intentional with it. But once I was on the other side, then I got to have a query object, which is a lot of fun. I love writing those. And I got to build pagination in Inertia, which is also one of those things that I really love. This is a place where Inertia really shines. It's incredibly performant. It allows you to do all of this stuff but in a familiar Rails way but yet still have fancy UI on the front end and just an intersection of some of my favorite things. So the refactoring both paid off in terms of what we got in the application but also was just fun at the end. Well, not the refactoring; the thing that came after the refactoring was fun. STEPH: Nice. Well, speaking of being nervous about breaking things, I am feeling very determined right now where I want to delete some code. And I have that nervousness around I'm going to break something. But I've spent enough time with this code to feel confident that it's not truly in use. But knowing the exact entry point for that code is part of the CI script process. So I don't have full control over the entry points. It's something that I'm having to coordinate with another team to verify, like, hey, I'm pretty sure it's a script that's never called and never used, or at least this particular path we're not passing these particular flags to the script. And going through the code caused enough confusion for me that if I can simplify this and get rid of that code, I'd really like to. So I'm at that point where I'm feeling good. I'm going to issue a change that deletes the code. But there's definitely a part of me that's nervous because it's one of those like, somewhere someone could be running this script on their machine locally. Or they could be using it as part of a different build process that I'm not aware of, which worst-case, then we realize something breaks, and then we have to roll it back. But it feels like one of those important I'm going to do it while I've got the context. Let's delete the code. Let's see what breaks. Someone mentioned to me earlier there's the idea of the screen test where you delete something, and then you just wait, and you see who starts screaming. [laughs] I was like, yeah, that's exactly what I want to do. I've done more validation upfront. I don't want anybody to scream. But that's essentially the metric that I'm then going to go off of once we do merge this in and see how it goes. But it felt like one of those interesting conversations with myself and someone else that was then looking at it with me where we could easily leave it. We could just walk away. Because I saw this code while I was working on something else, and then I really needed to assess whether I needed to alter this code as well or whether I could leave it alone. And I've decided I could leave it alone for this reason. So it's one of those moments of like, okay, well, I could just walk away. I've done the thing that I needed to do for my change. But it feels important to go ahead and follow-through that while I have all of this context. So let's just go ahead and delete it, so someone else doesn't have to build up all that context. CHRIS: As you're describing this, I'm sort of thinking of my own career arc as a developer. And early on, I'd just be like, it's fine, we'll just change it now. Nothing will go wrong. And then, obviously, something goes wrong. And slowly, over time, I've built up enough battle wounds from that that I was like, you know what? I'm hesitant to change it. I'm a little scared. What if we break production? And so then, there was a period of a couple of years where I would probably be more hesitant to change things. And then eventually I got to the place where I'd seen the cost of not changing the thing when you have the context and letting the less correct implementation or the incorrect domain modeling sit and grow and become worse over time, and then the deep pain that you can feel down the road. And so now I'm like yeah, no, we're probably going to feel some pain on this change. Somebody is going to yell, but we should do it, and that's it. And I like thinking about that arc of just brazen confidence to oh God; everything's terrible to a different type of confidence. Like, yeah, I know something is going to break. But sometimes you got to crack some eggs, you know. STEPH: And it's one of those areas where if we do find out something breaks and someone reports like, "Oh, this is really critical, and you took this away from me," then that's great, at least now I've got validation we know where it's used. And then we can; I don't know, maybe somewhere document that somehow or at least we don't even have to document it. But we just at least know that this is a valid code path that needs to be supported, and then I'll feel better about that. Versus in this world right now, I'm in the I don't think this is important, but I don't have solid proof that it's not important, but I'm not going to treat it important. And that feels like the worst place to be. I want to know if this is valid or not. So this will help push us in that direction. But yeah, I like that arc that you described. I can definitely relate to that. CHRIS: I definitely share the hesitancy and the worry that like, man, is this going to silently break something that someone relies on? But if that's true, then that means our test suite is missing something. If this is a critical code path and I could just delete it, and the test suite is like, cool, that seems fine, then we have a gap in our code coverage. And I don't mean code coverage in the percentage metric; I mean it in the an important thing is not enforced by the test suite. And so it's a complicated and messy way to find out what's missing from our test suite, but it is a way. Just remove it and see then what happens. And then we backfill in the test suite to say, "Oh gosh, we should have had that. Deleting that was bad." STEPH: So I absolutely agree with what you're saying. This particular scenario is a little tricky because the entry point isn't a traditional user-driven action or something that I feel more concrete that I can test a user flow even if it had test coverage, which it doesn't right now. But even if it had test coverage, it would be part of our CI process then calls this script, and then we expect the script to behave and respond as expected. But even then, if we had that test, we could still have unused code. It could still be a path that just doesn't need to be supported. I guess as I'm saying this, that could be true of a user flow as well. I just talked myself into that; cool. [laughs] Yeah, it's one of those even if we had tests that wouldn't give me the full confidence to know whether we have a valid path or not, that needs to be supported. So it feels a bit tricky in that regard. Because I am so used to then relying on my tests to help me know that yes, this is something that's important to the application or not. And in this case, I don't think that actually helps me. I think honestly, at this point, it's talking to people who have built a lot of the infrastructure in their CI system to say, "Hey, can you help me track down? I've looked at all the places that I know to look. I even issued a change that raises." So if that script was getting called, then something in the CI infrastructure should have blown up to let me know. So I've taken all the incremental steps that I can to see if anything breaks. And so far, nothing's breaking yet, but we just won't know until it's gone. Comparing this to previous situations, it does feel like one of those areas where if I was uncertain about if something is in use, that looking at the test is always helpful but then also having a product manager to go to because then that person can confirm yes, this is something that I'm certain that someone still uses, or we need to support. Or they can say, "You know what? Even if it is something that someone is using, we don't wish to support this feature anymore, and we'd like to get rid of it." It feels like I'm in that space. But there's not a clear product manager. Now, for this one, there is someone very knowledgeable who helped build a lot of this system that I can go to. So in effect, they are acting as that person that can then let me know to say yes; even though we have code to support this path, I'm pretty sure we don't want to support it anymore, and we can get rid of it. So that's ultimately what's given me the confidence to move forward with the change. Mid-roll Ad Hi, friends, and now a quick break to hear from today's sponsor, Scout APM. Scout APM is an application performance monitoring tool that's designed to help developers find and fix performance issues quickly. With an intuitive user interface, Scout will tie bottlenecks to source code, so you can quickly pinpoint and resolve performance abnormalities like N+1 queries, slow database queries, and memory bloat. Scout also recently implemented external service monitoring, adding even more granularity when it comes to HTTP requests and API calls. So give Scout a try today with a free 14-day trial and experience first-hand why developers worldwide call Scout their best friend. And as an added bonus for Bike Shed listeners, Scout will donate $5 to the open-source project of your choice when you deploy. To learn more, visit scoutapm.com/bikeshed. That's scoutapm.com/bikeshed. Pivoting just a bit, we have a listener question. And this question comes from Slash. And they wrote in, "What are the first keyboard shortcuts you teach junior devs? What is so powerful that can explain to juniors why it's important to know them?" Yeah, all right. I have thoughts. Chris, do you want me to kick us off, or do you want to kick us off? CHRIS: This is an interesting one because, for folks that have seen some of my internet movements, you will know that I am a fan of the keyboard and shortcuts there. And I like Vim; I like Tmux. I do not like things that require me to use my mouse. And so, my answer might be somewhat surprising, but I actually try to avoid this. I think the trap of productivity enhancements and whatnot can be, especially early on, a way to distract from the real work. There's so much as a junior dev to learn and, especially if you're a web developer, and I'm imagining this is potentially like full-stack web dev. But even if you're a front-end developer, there's a just world of complexity that you have now opened up. You need to understand about HTTP, and CSS, and HTML, and JavaScript, and TypeScript, and there are so, so many things. And so if there's anything we can take off of our plates at that point, I think that's really useful. So my very clear suggestion to folks that are new is just use VS Code seems like it's great. It's got a ton of stuff built-in. It's going to work well, and you can get really far with it. And there's a point in time that you will get to where you feel like maybe that tool is slowing you down, although my understanding is VS Code is a really impressive piece of technology. And so if you're not as deeply drawn to keyboard-only as I am, then VS Code you can keep growing within that. There are so many enhancements and customizations and whatnot that you can do there. But it's weird that my answer is kind of like none or deflect the question and say, do these cutters around Ruby and Rails and JavaScript or whatever the language or framework or whatever it is that you're working in. But that's my first approximation. I probably have a more real set of answers. But I'm interested in your response to that or your thoughts on that, Steph. STEPH: I love that. I think you make such a good point that you are entering a world where there's so much to learn that I don't think this is of high importance. It is something that you can cultivate over the years but not something that you need to focus on. And when you highlighted using VS Code instead of saying our de facto like Vim, which is something that you and I love, I thought about that because Tim, my husband, went through a coding bootcamp recently. And I don't know if I'd shared this, but he just got his first job as a junior dev. So that's incredibly exciting. And when we were talking about editors to use, VS Code was one of my top ones. I just know it's well built; it's popular. It does a lot for you. And it's just that way; you can focus on everything else that you mentioned that junior devs are often having to focus on that then at that point, it really becomes all the shortcuts for you to learn. It's just get to know your editor. Understand how to do the fuzzy search for files or a specific method. How do you split windows? How do you make it easy to toggle between running your testing code? But I do think it's important to become familiar with those shortcuts and commands so that way you feel very competent and productive in your editor. Whatever your editor is, just get to know those commands. To go a bit broader with it, I do think there are some things that are really helpful to know. And I'm also working off the assumption that if you're a junior dev, you probably already know the basics. You know the copying and pasting, refreshing a page, and undoing a change. So some of the keyboard shortcuts or tooling that would be more helpful, in my opinion, is as learning your editor, learn some terminal shortcuts. So like pressing up to rerun the last command, I think that's probably one of the first things that if I don't see someone doing that, I would remind them or let them know that they can do. I also think it's really awesome to have a command-line tool like fzf that lets you find and filter files or search through your command history because I use that all the time. So I'm constantly just searching through my command history in my terminal so I can rerun commands versus having to remember what to type. And then also, I mean, there are a couple of basic browser shortcuts, so navigating between tabs, opening new tabs. And then the big one is Git. If you're using Git for your job, spend time with Git, and that doesn't really fall into the whole keyboard shortcuts. That's a whole different topic. So I'm totally cheating here. But I think it's important enough to focus on that over the keyboard shortcuts is get good at writing commit messages, amending changes, viewing a history, and how to rebase, things like that. CHRIS: I think the list that you gave there is actually a really practical one of, like, learn how to move around within your editor and in between the files because that's going to be a thing that you're just constantly doing. And so I'm also a huge fan of fuzzy finding, so Ctrl+P in the Vim world or fzf that you listed as a more generic utility that has it. I know VS Code has a command palette where you can fuzzy search for files and different variations there. And that is such a nice way to work. I don't actually want keyboard shortcuts, if we're being honest. This is maybe a somewhat heretical thing, but I want modes. I love Vim's modes, and there's a whole language there. I made a YouTube video a while back about it because I believe in it so strongly. But it's that idea of like, if I have to remember these arcane movements of my fingers, that's not fun for me. I want the computer to learn me rather than me it. And so fuzzy finding anything, being able to type any substring of the things that you're matching against is such a powerful way to interact with stuff that's like, it's not me knowing the magic key command to do something; it's the computer understanding me a little bit better. You also listed being able to run a test file or an individual test. I love that one. That is something that I use constantly. And so that's one that I think would be worth investing in because being able to get that iteration loop of make a change, run the test, make another change, run the test again. That's a really powerful one to refine. The other thing probably we're saying is take a look at your own workflow and look at what's somewhat painful and then Google, like, how do I get better at that? And the Internet will have things to say on that front. I definitely agree with what you were saying about the command line. That's a place that is a little bit hostile to folks when they first show up. Like, what is this place, and why is it kind of mean? But it can be refined and honed, and tweaked. And so that's a place, again, fzf as a utility, there is a particular one. Again, not quite a keyboard shortcut, though. It's more of a utility; it's a command, a tool, I don't know. Pipeline some stuff; it'll be fun. I will somewhat back out of what I said earlier, though, of I don't recommend that folks try and push on this too much early on. And the reason I'll say that is a while back, I taught a cohort of Metis, which was the bootcamp that thoughtbot was involved in many, many years ago. Uniformly in each cohort that I at least knew about, the instructor started with that ethos of like, okay, we're going to be up here and demoing things. We're using this thing called Vim. It's weird. Don't worry about it, though. You don't need to learn that. You shouldn't learn that. You should focus on the Rails and the Ruby and JavaScript that we're teaching you. That's the focus. But essentially, without fail, the students were like, "Yeah, but that thing looks cool. Tell us more about that thing." And so they ended up, these are the folks who designed the course before I started teaching it, they ended up bringing that in as like this is a Friday show and tell sort of thing. All right, we're going to tell you about Vim because everybody keeps asking about it. And then most of the students ended up using Vim because watching the way someone moves in Vim if you've not seen it and if you're not familiar with that, you're like, wow, you're just moving around the file like magic. It's amazing. And that was certainly my experience before I used Vim. And watching someone using, I'm just like, wow, okay, I want that though. That's the thing that I need. So there's this delicate line of like, I would recommend ignoring this. But I get that if you see that, you're like, I would be so much more efficient if I could use that, and it's true to a certain extent. So yeah, my recommendation would be don't do that. But most folks that I've seen are like, I would like to get better at these tools, and I totally get that. And I've obviously spent a lot of my own personal time [laughs] getting there. So I feel like I'm a do as I say, not as I do, maybe sort of thing. [laughs] It's roughly the space that I'm coming from right now. And I don't love being in that space, but apparently, it's where I find myself in this moment. STEPH: That feels like a nice thing to share, though, because that is something that you've really enjoyed and cultivating that craft, and then sharing that and creating videos and content around it. So that totally makes sense that you can say, like, this is something I enjoy, and I have found it productive and helpful. Maybe sometimes you negotiate how productive it is. CHRIS: Jury is out. STEPH: [laughs] You've enjoyed it. And so it's something that you've chosen to invest in, but you don't feel it's critical to anybody else and their career or their path that they should invest in it. It does make sense that from a teacher-student perspective that, you're going to want to emulate what your teacher is doing. So in the past, when I've taught very beginner-friendly intro to web development classes, so I would say much earlier than a junior dev, I always made sure to use VS Code or whatever editor I was using with them because I wanted to mimic exactly what they were going to do and have that same environment versus showing them something completely different and then expect them to translate. So there could be some parallelisms there as well if you're working with a junior developer that you want to cater to an environment that they can work with and feel comfortable and grow with versus showing them all of the fancy trickery that you can do in your particular setup. CHRIS: Another data point in Steph is a better person than me. STEPH: Sure, I'll take it. [laughter] There was also an interesting part of the question about what's so powerful that can explain to juniors why it's so important to know these keyboard shortcuts? And the only thing I could come up with because, again, I don't think it's super important for junior devs to learn keyboard shortcuts...but for the stuff that we do think is important around becoming familiar with your editor, making your terminal more friendly, for that stuff, I think a lot of it comes down to..., or the best reason I can think of is for your health. Because it's been known that there's an increased risk of RSI the more that you switch between your keyboard and your mouse. So if you can use more keyboard shortcuts and use less or place less strain on your wrist and fingers by having to switch from your mouse to your keyboard, then I think that's the best reason. I mean, sure, productivity and feeling like a wizard those are cool reasons, but your health is really the only important reason. I just realized I used an initialism, but I didn't provide the definition for it. So for anyone that's not familiar, RSI stands for Repetitive Stress Injury. CHRIS: It's interesting that you highlight the health aspect and RSI in particular because it's not something that I think about, but I think is definitely a benefit that I've had and what I like about modal editing and what I like about Vim. I think I tend to think about it in a different way, or it's the same idea but rotated around 180 degrees or something where my ability to do something quickly is not important in and of itself. But my ability to stay in context when I've figured out the change that I need to make that matters to me immensely. And so what you're talking about of like being able to move quickly between files, being able to run the tests, being able to determine if the change that I made was, in fact, the correct change I care immensely about that. Because typing is not the bottleneck is a phrase that gets thrown around, and I like that phrase because it's true. It's not about just being faster at the keyboard and being an elite hacker typing all day long. The hard part is the thinking. But once I've done that, I want to get that thought out of my head and into the code as quickly as possible, as directly as possible. And having efficient tooling and the ability to work with that tooling and move between files and run the tests and all of that is critically important to me for that reason, not because any individual change needs to be made that quickly but because once I've done the hard part of the thinking, then I want to get it out of my head and into my hands and then into the editor. So now I think I've completely contradicted myself, or I've just slowly moved around this question of like, I don't think you should. Well, maybe you should, you should definitely is, I think, the three different stances that I've taken. But I do kind of believe that that should be something that changes over time in your career. So maybe I've been consistent if you give me that lens. STEPH: That's what's fun about these listener questions. They take us on journeys, and I love that answer. I love that it's more about the staying in context that then helps you feel so productive. It's not just a productivity goal that you're looking for. But it is more for your context that that way, if you know there's a change that you want to make and you don't feel held up by all these other little things that are then preventing you from getting whatever it is you're excited to get done, getting it done. But speaking of shortcuts, there is one that I just learned recently that's probably a pretty common one, but I haven't used it. I happened to stumble upon it. So if you're in your browser, you can open up a new tab, Command+T; I'm on a Mac. So you can do Command+T and open a new tab. But there have been many times where I've accidentally closed a tab, or I've had a couple open, and I clicked the little close on the wrong one, and I'm like, no. And then I have to figure out where I was or go back to my history. But there's a shortcut for that, and it is Command+Shift+T, and that will reopen the tab that you accidentally closed. Didn't know that, learned that today. I'm going to lock that one away because that should be helpful. CHRIS: The best way to lock it away is to explain it to others. So now that you've done that, this one's yours forever. Whereas everyone else hearing it, you got to try it a few times before it'll be yours forever, but, Steph, you're good now. STEPH: Or spin up your own podcast and then share your keyboard shortcuts so that you can lock it away. [laughs] CHRIS: I've observed that to be the easiest way to instill any learnings deeply within my brain. STEPH: On that note, shall we wrap up? CHRIS: Let's wrap up. The show notes for this episode can be found at bikeshed.fm. STEPH: This show is produced and edited by Mandy Moore. CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes, as it really helps other folks find the show. STEPH: If you have any feedback for this or any of our other episodes, you can reach us at @_bikeshed or reach me on Twitter @SViccari. CHRIS: And I'm @christoomey. STEPH: Or you can reach us at [email protected] via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!! ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.Sponsored By:Scout: Scout APM is leading-edge application performance monitoring designed to help Rails developers quickly find and fix performance issues without having to deal with the headache or overhead of enterprise-platform feature bloat. With a developer-centric UI and tracing logic that ties bottlenecks to source code, you can quickly pinpoint and resolve performance abnormalities -- like N+1 queries, slow database queries, memory bloat, and more. Scout's real-time alerting and weekly digest emails let you rest easy knowing Scout's on watch and resolving performance issues before your customers ever see them. Scout has also launched its new error monitoring feature add-on for Python applications. Now you can connect your error reporting and application monitoring data on one platform. See for yourself why developers worldwide call Scout their best friend and try our error monitoring and APM free for 14-days, no credit card needed! And as an added bonus for Bikeshed listeners: Scout will donate $5 to the open-source project of your choice when you deploy. Learn more at scoutapm.com/bikeshed.Support The Bike Shed