The Bike Shed cover image

The Bike Shed

Latest episodes

undefined
Sep 13, 2022 • 31min

354: The History of Computing

Why does the history of computing matter? Joël and Developer at thoughtbot Sara Jackson, ponder this and share some cool stories (and trivia!!) behind the tools we use in the industry. This episode is brought to you by Airbrake. Visit Frictionless error monitoring and performance insight for your app stack. Sara on Twitter UNIX philosophy Hillel Wayne on why we ask linked list questions History of Unix, Linux, and Open Source / Free Software Collected Histories of Unix Selected pages from the nine research editions of the UNIX® Programmer’s Manual illustrate the development of the system. Accompanying commentary recounts some of the needs, events, and individual contributions that shaped this evolution These are dates that every hacker knew were important at the time, or shortly afterwards. Unix at 50: How the OS that powered smartphones started from failure First hand account of history of Unix and Multics by Tom Van Vleck Transcript: JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. And today, I'm joined by fellow thoughtboter, Team Lead, and Developer Sara Jackson. SARA: Hello, happy to be here. JOËL: Together, we're here to share a little bit of what we've learned along the way. So, Sara, what's new in your world? SARA: Well, Joël, you might know that recently our team had a small get-together in Toronto. JOËL: And our team, for those who are not aware, is fully remote distributed across multiple countries. So this was a chance to get together in person. SARA: Yes, correct. This was a chance for those on the Boost team to get together and work together as if we had a physical office. JOËL: Was this your first time meeting some members of the team? SARA: It was my second, for the most part. So I joined thoughtbot, but after thoughtbot had already gotten remote. Fortunately, I was able to meet many other thoughtboters in May at our summit. JOËL: Had you worked at a remote company before coming to thoughtbot? SARA: Yes, I actually started working remotely in 2019, but even then, that wasn't my first time working remotely. I actually had a full year of internship in college that was remote. JOËL: So you were a pro at this long before the pandemic made us all try it out. SARA: I don't know about that, but I've certainly dealt with the idiosyncrasies that come with remote work for longer. JOËL: What do you think are some of the challenges of remote work as opposed to working in person in an office? SARA: I think definitely growing and maintaining a culture. When you're in an office, it's easy to create ad hoc conversations and have events that are small that build on the culture. But when you're remote, it has to be a lot more intentional. JOËL: That definitely rings true for me. One of the things that I really appreciated about in-person office culture was the serendipity that you have those sort of random meetings at the water cooler, those conversations, waiting for coffee with people who are not necessarily on the same team or the same project as you are. SARA: I also really miss being able to have lunch in person with folks where I can casually gripe about an issue I might be having, and almost certainly, someone would have the answer. Now, if I'm having an issue, I have to intentionally seek help. [chuckles] JOËL: One of the funny things that often happened, at least the office where I worked at, was that lunches would often devolve into taxonomy conversations. SARA: I wish I had been there for that. [laughter] JOËL: Well, we do have a taxonomy channel on Slack to somewhat continue that legacy. SARA: Do you have a favorite taxonomy lunch discussion that you recall? JOËL: I definitely got to the point where I hated the classifying a sandwich. That one has been way overdone. SARA: Absolutely. JOËL: There was an interesting one about motorcycles, and mopeds, and bicycles, and e-bikes, and trying to see how do you distinguish one from the other. Is it an electric motor? Is it the power of the engine that you have? Is it the size? SARA: My brain is already turning on those thoughts. I feel like I could get lost down that rabbit hole very easily. [laughter] JOËL: Maybe that should be like a special anniversary episode for The Bike Shed, just one long taxonomy ramble. SARA: Where we talk about bikes. JOËL: Ooh, that's so perfect. I love it. One thing that I really appreciated during our time in Toronto was that we actually got to have lunch in person again. SARA: Yeah, that was so wonderful. Having folks coming together that had maybe never worked together directly on clients just getting to sit down and talk about our day. JOËL: Yeah, and talk about maybe it's work-related, maybe it's not. There's a lot of power to having some amount of deeper interpersonal connection with your co-workers beyond just the we work on a project together. SARA: Yeah, it's like camaraderie beyond the shared mission of the company. It's the shared interpersonal mission, like you say. Did you have any in-person pairing sessions in Toronto? JOËL: I did. It was actually kind of serendipitous. Someone was stuck with a weird failing test because somehow the order factories were getting created in was not behaving in the expected way, and we herd on it, dug into it, found some weird thing with composite primary keys, and solved the issue. SARA: That's wonderful. I love that. I wonder if that interaction would have happened or gotten solved as quickly if we hadn't been in person. JOËL: I don't know about you, but I feel like I sometimes struggle to ask for help or ask for a pair more when I'm online. SARA: Yeah, I agree. It's easier to feel like you're not as big of an impediment when you're in person. You tap someone on the shoulder, "Hey, can you take a look at this?" JOËL: Especially when they're on the same team as you, they're sitting at the next desk over. I don't know; it just felt easier. Even though it's literally one button press to get Tuple to make a call, somehow, I feel like I'm interrupting more. SARA: To combat that, I've been trying to pair more frequently and consistently regardless of if I'm struggling with a problem. JOËL: Has that worked pretty well? SARA: It's been wonderful. The only downside has been pairing fatigue. JOËL: Pairing fatigue is real. SARA: But other than that, problems have gotten solved quickly. We've all learned something for those that I've paired with. It goes faster. JOËL: So it was really great that we had this experience of doing our daily work but co-located in person; we have these experiences of working together. What would you say has been one of the highlights for you of that time? SARA: 100% karaoke. JOËL: [laughs] SARA: Only two folks did not attend. Many of the folks that did attend told me they weren't going to sing, but they were just going to watch. By the end of the night, everyone had sung. We were there for nearly three and a half hours. [laughs] JOËL: It was a good time all around. SARA: I saw a different side to Chad. JOËL: [laughs] SARA: And everyone, honestly. Were there any musical choices that surprised you? JOËL: Not particularly. Karaoke is always fun when you have a group of people that you trust to be a little bit foolish in front of to put yourself out there. I really appreciated the style that we went for, where we have a private room for just the people who were there as opposed to a stage in a bar somewhere. I think that makes it a little bit more accessible to pick up the mic and try to sing a song. SARA: I agree. That style of karaoke is a lot more popular in Asia, having your private room. Sometimes you can find it in major cities. But I also prefer it for that reason. JOËL: One of my highlights of this trip was this very sort of serendipitous moment that happened. Someone was asking a question about the difference between a Mac and Linux operating systems. And then just an impromptu gathering happened. And you pulled up a chair, and you're like, gather around, everyone. In the beginning, there was Multics. It was amazing. SARA: I felt like some kind of historian or librarian coming out from the deep. Let me tell you about this random operating system knowledge that I have. [laughs] JOËL: The ancient lore. SARA: The ancient lore in the year 1969. JOËL: [laughs] And then yeah, we had a conversation walking the history of operating systems, and why we have macOS and Linux, and why they're different, and why Windows is a totally different kind of family there. SARA: Yeah, macOS and Linux are sort of like cousins coming from the same tree. JOËL: Is that because they're both related through Unix? SARA: Yes. Linux and macOS are both built based off of different versions of Unix. Over the years, there's almost like a family tree of these different Nix operating systems as they're called. JOËL: I've sometimes seen asterisk N-I-X. This is what you're referring to as Nix. SARA: Yes, where the asterisk is like the RegEx catch-all. JOËL: So this might be Unix. It might be Linux. It might be... SARA: Minix. JOËL: All of those. SARA: Do you know the origin of the name Unix? JOËL: I do not. SARA: It's kind of a fun trivia piece. So, in the beginning, there was Multics spelled M-U-L-T-I-C-S, standing for the Multiplexed Information and Computing Service. Dennis Ritchie and Ken Thompson of Bell Labs famous for the C programming language... JOËL: You may have heard of it. SARA: You may have heard of it maybe on a different podcast. They were employees at Bell Labs when Multics was being created. They felt that Multics was very bulky and heavy. It was trying to do too many things at once. It did have a few good concepts. So they developed their own smaller Unix originally, Unics, the Uniplexed Information and Computing Service, Uniplexed versus Multiplexed. We do one thing really well. JOËL: And that's the Unix philosophy. SARA: It absolutely is. The Unix philosophy developed out of the creation of Unix and C. Do you know the four main points? JOËL: No, is it small sharp tools? It's the main one I hear. SARA: Yes, that is the kind of quippy version that has come out for sure. JOËL: But there is a formal four-point manifesto. SARA: I believe it's evolved over the years. But it's interesting looking at the Unix philosophy and seeing how relevant it is today in web development. The four points being make each program do one thing well. To this end, don't add features; make a new program. I feel like we have this a lot in encapsulation. JOËL: Hmm, maybe even the open-closed principle. SARA: Absolutely. JOËL: Similar idea. SARA: Another part of the philosophy is expecting output of your program to become input of another program that is yet unknown. The key being don't clutter your output; don't have extraneous text. This feels very similar to how we develop APIs. JOËL: With a focus on composability. SARA: Absolutely. Being able to chain commands together like you see in Ruby all the time. JOËL: I love being able to do this, for example, the enumerable API in Ruby and just being able to chain all these methods together to just very nicely do some pretty big transformations on an array or some other data structure. SARA: 100% agree there. That ability almost certainly came out of following the tenets of this philosophy, maybe not knowingly so but maybe knowingly so. [chuckles] JOËL: So is that three or four? SARA: So that was two. The third being what we know as agile. JOËL: Really? SARA: Yeah, right? The '70s brought us agile. Design and build software to be tried early, and don't hesitate to throw away clumsy parts and rebuild. JOËL: Hmmm. SARA: Even in those days, despite waterfall style still coming on the horizon. It was known for those writing software that it was important to iterate quickly. JOËL: Wow, I would never have known. SARA: It's neat having this history available to us. It's sort of like a lens at where we came from. Another piece of this history that might seem like a more modern concept but was a very big part of the movement in the '70s and the '80s was using tools rather than unskilled help or trying to struggle through something yourself when you're lightening a programming task. We see this all the time at thoughtbot. Folks do this many times there is an issue on a client code. We are able to generalize the solution, extract into a tool that can then be reused. JOËL: So that's the same kind of genesis as a lot of thoughtbot's open-source gems, so I'm thinking of FactoryBot, Clearance, Paperclip, the old-timey file upload gem, Suspenders, the Rails app generator, and the list goes on. SARA: I love that in this last point of the Unix philosophy, they specifically call out that you should create a new tool, even if it means detouring, even if it means throwing the tools out later. JOËL: What impact do you think that has had on the way that tooling in the Unix, or maybe I should say *Nix, ecosystem has developed? SARA: It was a major aspect of the Nix environment community because Unix was available, not free, but very inexpensively to educational institutions. And because of how lightweight it was and its focus on single-use programs, programs that were designed to do one thing, and also the way the shell was allowing you to use commands directly and having it be the same language as the shell scripting language, users, students, amateurs, and I say that in a loving way, were able to create their own tools very quickly. It was almost like a renaissance of Homebrew. JOËL: Not Homebrew as in the macOS package manager. SARA: [laughs] And also not Homebrew as in the alcoholic beverage. JOËL: [laughs] So, this kind of history is fun trivia to know. Is it really something valuable for us as a jobbing developer in 2022? SARA: I would say it's a difficult question. If you are someone that doesn't dive into the why of something, especially when something goes wrong, maybe it wouldn't be important or useful. But what sparked the conversation in Toronto was trying to determine why we as thoughtbot tend to prefer using Macs to develop on versus Linux or Windows. There is a reason, and the reason is in the history. Knowing that can clarify decisions and can give meaning where it feels like an arbitrary decision. JOËL: Right. We're not just picking Macs because they're shiny. SARA: They are certainly shiny. And the first thing I did was to put a matte case on it. JOËL: [laughs] So no shiny in your office. SARA: If there were too many shiny things in my office, boy, I would never get work done. The cats would be all over me. MID-ROLL AD: Debugging errors can be a developer’s worst nightmare...but it doesn’t have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers, that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake’s debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake’s lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! JOËL: So we've talked a little bit about Unix or *Nix, this evolution of systems. I've also heard the term POSIX thrown around when talking about things that seem to encompass both macOS and Linux. How does that fit into this history? SARA: POSIX is sort of an umbrella of standards around operating systems that was based on Unix and the things that were standard in Unix. It stands for the Portable Operating System Interface. This allowed for compatibility between OSs, very similar to USB being the standard for peripherals. JOËL: So, if I was implementing my own Unix-like operating system in the '80s, I would try to conform to the POSIX standard. SARA: Absolutely. Now, not every Nix operating system is POSIX-compliant, but most are or at least 90% of the way there. JOËL: Are any of the big ones that people tend to think about not compliant? SARA: A major player in the operating system space that is not generally considered POSIX-compliant is Microsoft Windows. JOËL: [laughs] It doesn't even try to be Unix-like, right? It's just its own thing, SARA: It is completely its own thing. I don't think it even has a standard necessarily that it conforms to. JOËL: It is its own standard, its own branch of the family tree. SARA: And that's what happens when your operating system is very proprietary. This has caused folks pain, I'm sure, in the past that may have tried to develop software on their computers using languages that are more readily compatible with POSIX operating systems. JOËL: So would you say that a language like Ruby is more compatible with one of the POSIX-compatible operating systems? SARA: 100% yes. In fact, to even use Ruby as a development tool in Windows, prior to Windows 10, you needed an additional tool. You needed something like Cygwin or MinGW, which were POSIX-compliant programs that it was almost like a shell in your Windows computer that would allow you to run those commands. JOËL: Really? For some reason, I thought that they had some executables that you could run just on Windows by itself. SARA: Now they do, fortunately, to the benefit of Ruby developers everywhere. As of Windows 10, we now have WSL, the Windows Subsystem for Linux that's built-in. You don't have to worry about installing or configuring some third-party software. JOËL: I guess that kind of almost cheats by just having a POSIX system embedded in your non-POSIX system. SARA: It does feel like a cheat, but I think it was born out of demand. The Windows NT kernel, for example, is mostly POSIX-compliant. JOËL: Really? SARA: As a result of it being used primarily for servers. JOËL: So you mentioned the Ruby tends and the Rails ecosystem tends to run better and much more frequently on the various Nix systems. Did it have to be that way? Or is it just kind of an accident of history that we happen to end up with Ruby and Rails in this ecosystem, but just as easily, it could have evolved in the Windows world? SARA: I think it is an amalgam of things. For example, Unix and Nix operating systems being developed earlier, being widely spread due to being license-free oftentimes, and being widely used in the education space. Also, because it is so lightweight, it is the operating system of choice. For most servers in the world, they're running some form of Unix, Linux, or macOS. JOËL: I don't think I've ever seen a server that runs macOS; exclusively seen it on dev machines. SARA: If you go to an animation company, they have server farms of macOS machines because they're really good at rendering. This might not be the case anymore, but it was at one point. JOËL: That's a whole other world that I've not interacted with a whole lot. SARA: [chuckles] JOËL: It's a fun intersection between software, and design, and storytelling. That is an important part for the software field. SARA: Yeah, it's definitely an aspect that deserves its own deep dive of sorts. If you have a server that's running a Windows-based operating system like NT and you have a website or a program that's designed to be served under a Unix-based server, it can easily be hosted on the Windows server; it's not an issue. The reverse is not true. JOËL: Oh. SARA: And this is why programming on a Nix system is the better choice. JOËL: It's more broadly compatible. SARA: Absolutely. Significantly more compatible with more things. JOËL: So today, when I develop, a lot of the tooling that I use is open source. The open-source movement has created a lot of the languages that we know and love, including Ruby, including Rails. Do you think there's some connection between a lot of that tooling being open source and maybe some of the Unix family of operating systems and movements that came out of that branch of the operating system family tree? SARA: I think that there is a lot of tie-in with today's open-source culture and the computing history that we've been talking about, for example, people finding something that they dislike about the tools that are available and then rolling their own. That's what Ken Thompson and Dennis Ritchie did. Unix was not an official Bell development. It was a side project for them. JOËL: I love that. SARA: You see this happen a lot in the software world where a program gets shared widely, and due to this, it gains traction and gains buy-in from the community. If your software is easily accessible to students, folks that are learning, and breaking things, and rebuilding, and trying, and inventing, it's going to persist. And we saw that with Unix. JOËL: I feel like this background on where a lot of these operating systems came but then also the ecosystems, the values that evolved with them has given me a deeper appreciation of the tooling, the systems that we work with today. Are there any other advantages, do you think, to trying to learn a little bit of computing history? SARA: I think the main benefit that I mentioned before of if you're a person that wants to know why, then there is a great benefit in knowing some of these details. That being said, you don't need to deep dive or read multiple books or write papers on it. You can get enough information from reading or skimming some Wikipedia pages. But it's interesting to know where we came from and how it still affects us today. Ruby was written in C, for example. Unix was written in C as well, originally Assembly Language, but it got rewritten in C. And understanding the underlying tooling that goes into that that when things go wrong, you know where to look. JOËL: I guess that that is the next question is where do you look if you're kind of interested? Is Wikipedia good enough? You just sort of look up operating system, and it tells you where to go? Or do you have other sources you like to search for or start pulling at those threads to understand history? SARA: That's a great question. And Wikipedia is a wonderful starting point for sure. It has a lot of the abbreviated history and links to better references. I don't have them off the top of my head. So I will find them for you for the show notes. But there are some old esoteric websites with some of this history more thoroughly documented by the people that lived it. JOËL: I feel like those websites always end up being in HTML 2; your very basic text, horizontal rules, no CSS. SARA: Mm-hmm. And those are the sites that have many wonderful kernels of knowledge. JOËL: Uh-huh! Great pun. SARA: [chuckles] Thank you. JOËL: Do you read any content by Hillel Wayne? SARA: I have not. JOËL: So Hillel produces a lot of deep dives into computing history, oftentimes trying to answer very particular questions such as when and why did we start using reversing a linked list as the canonical interview question? And there are often urban legends around like, oh, it's because of this. And then Hillel will do some research and go through actual archives of messages on message boards or...what is that protocol? SARA: BBS. JOËL: Yes. And then find the real answer, like, do actual historical methodology, and I love that. SARA: I had not heard of this before. I don't know how. And that is all I'm going to be doing this weekend is reading these. That kind of history speaks to my heart. I have a random fun fact along those lines that I wanted to bring to the show, which was that the echo command that we know and love in the terminal was first introduced by the Multics operating system. JOËL: Wow. So that's like the most common piece of Multics that as an everyday user of a modern operating system that we would still touch a little bit of that history every day when we work. SARA: Yeah, it's one of those things that we don't think about too much. Where did it come from? How long has it been around? I'm sure the implementation today is very different. But it's like etymology, and like taxonomy, pulling those threads. JOËL: Two fantastic topics. On that wonderful little nugget of knowledge, let's wrap up. Sara, where can people find you online? SARA: You can find me on Twitter at @csarajackson. JOËL: And we will include a link to that in the show notes. SARA: Thank you so much for having me on the show and letting me nerd out about operating system history. JOËL: It's been a pleasure. The show notes for this episode can be found at bikeshed.fm. This show is produced and edited by Mandy Moore. 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. It really helps other folks find the show. If you have any feedback, you can reach us at @_bikeshed or reach me @joelquen on Twitter or at hosts@bikeshed.fm via email. Thank you so much for listening to The Bike Shed, and we'll see you next week. Byeeeeee!!!! 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:Airbrake: Deploy fearlessly and fix bugs faster with Airbrake Error & Performance Monitoring. Airbrake notifiers are available for all major programming languages and frameworks, and install in minutes, with an open-source SDK-based install and near-zero technical debt. Spend less time tracking down bugs and more time developing. Visit Frictionless error monitoring and performance insight for your app stack.Support The Bike Shed
undefined
Sep 6, 2022 • 38min

353: Mental Models

Mental models are metaphors that help us understand complex problems we work on. They can be a simplified roadmap over an infinite area of complexity. How does one come up with mental models? How are they useful? Are they primarily a solo thing, or can they be used to communicate with the team? What happens when your model is inaccurate? Today, Joël is joined by Eebs Kobeissi, a Developer and Dev Manager at You Need a Budget, to discuss. This episode is brought to you by Airbrake. Visit Frictionless error monitoring and performance insight for your app stack. Eebs on Twitter You Need a Budget Skill floors and skill ceilings Transcript: JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. And today, I'm joined by Eebs Kobeissi, a Developer and Dev Manager at You Need a Budget. EEBS: Hi, Joël. It's really good to be here. JOËL: And together, we're here to share a little bit about what we've learned along the way. So, Eebs, what's new in your world? EEBS: Oh, a whole lot. I'm a new dad, so I'm getting to experience all those things. But in the developer world, I've recently picked up programming on an ESP32, which controls LED lights. And so I'm having fun lighting up my office. JOËL: Is that like one of those little microboards, kind of like a Raspberry Pi? EEBS: Yeah, exactly. It's a little board that's compatible with the Arduino IDE. And I literally only played with it last weekend, so it's still very new to me. JOËL: Nice. Have you done any Arduino development or Raspberry Pi or anything like that before? EEBS: No, I have a Raspberry Pi that I run like a DNS server on, but I haven't done any actual programming. I did make an LED blink, which is pretty cool. JOËL: What kind of programming is required for a board like that? EEBS: From my understanding, it's either in Python or C. Those are, I think, the two languages that you can program on it. I definitely do not know C. And so I'm just going through a bunch of tutorials and reading some sample code. But I think if I ever end up trying to implement something more complex, I'll probably switch over to Python because that's a little more familiar. JOËL: So the coding feels fairly high level even though you're writing controller code for LEDs. EEBS: I hope so. I'd love to be able to take advantage of whatever abstractions I can. JOËL: Do you have any fun goals you're trying to do with this? Or is this just for the fun of trying a completely different environment than web development? EEBS: No, it's actually rooted in something visual. So I have these shelves behind me that are in my webcam when I'm in meetings or whatever. And so I want to be able to put a light strip across these shelves and have some sort of visual thing in the background. JOËL: Like LED mood ring? EEBS: Yeah, kind of. My eventual goal would be that as I'm talking, a little equalizer display pops up behind me. I thought that would be pretty neat. JOËL: That is amazing. That will give you all of the cred in the meetings. EEBS: Right? I thought that'd be pretty cool. What have you been thinking about recently, Joël? JOËL: I've been submitting to the RubyConf call for proposals which, as of the recording of this episode, has just closed this week. And like many people, I submitted on the last day. EEBS: [laughs] JOËL: And it was really fun trying to take some ideas that I'm excited about and then turn them into a proposal that is accessible to other people. EEBS: Nice. Do you want to share a little bit about what the talk is, or is it under wraps for now? JOËL: I don't know if anyone on the committee will listen to this before the review goes out. This might break the anonymity of the proposal. EEBS: Oh, right, right. JOËL: One thing I will share that's interesting is that there are topics that I'm excited about. It's like, oh, here are a bunch of cool things about something, some technical topic. But talks that are just ten cool things about X are not that great. And so I needed to find some sort of unifying idea that I could use to share that. And that generally is in the form of trying to find a story that I can tell. What unifies all of these things together? What tells a compelling story? Is there some metaphor I can lean into? EEBS: Nice. I think that's a really powerful way of communicating something deeper is through telling something that people can relate to. JOËL: One way that thinking about metaphors has been really impactful for me recently is the idea of mental models and how those can help us in development. I'm curious; we've thrown around the phrase a little bit you and I in past conversations; what does a mental model mean to you? EEBS: I tend to be a visual thinker. And from talking to others, I've heard similar statements. So for me, a mental model is how I think about a particular domain or how I think about code flow or structure. And for me, it's usually either as two-dimensional objects or occasionally three-dimensional objects that I have floating in my visual space. So, for example, if we had two classes that are collaborators in some way, I often think of them maybe as two rectangles that are side by side. And when they interact, there's some little amorphous blob from one of those rectangles that reaches out into the other one or passes a message from one to the other. And I sort of have this idea of how many connections are there between these two physical things. Or, if I'm thinking about code flow and the path of execution that code might take, sometimes I visualize it as maybe a tree or potentially loops if there are such cases. JOËL: So when you think of these concepts, just in general, you're seeing in your mind's eye squares and rectangles floating in the air. EEBS: Yeah, pretty often. Sometimes it takes those shapes, and as I build up a mental model of some code, I'm usually adding new shapes into that picture I have in my mind. I tend to view things sort of top-down. So like, the start of code or the start of execution is usually at the top or maybe the far left or far right. And as execution happens, I usually view that as moving in towards the middle and potentially going back out when a response is returned. If it's a web request, something like that, I view it as this sort of outside in. And there's a bunch of pieces in there that are all talking to each other. JOËL: That's really cool. So not only is there a geometric aspect to it, but there's a spatial aspect to it as well. EEBS: Yeah. And it's interesting, like, I haven't actually thought about it [laughs] in this level of detail before. But yeah, there certainly is a spatial aspect to it. And I have this idea in my mind of like things and domain objects kind of belong at the bottom, and they should have well-defined boundaries. But the pieces that are a little bit towards the outer edges may be a little more fuzzy and may have less definition around them. JOËL: That's really interesting because I also have this sort of in my mind's eye see these things when I'm thinking about concepts like that. But I've talked to other people, and some people don't even have much of a mind's eye at all. They don't tend to visualize things in their mind in that way. EEBS: Yeah, it's really interesting how different people approach this thinking about code. A lot of people write things down. And I write things down, too, and draw little arrows that don't really make any sense. But it helps me do something physically sometimes as well as just thinking about it. JOËL: Have you ever tried to convert these pictures you see in your mind and actually draw them on paper? EEBS: Occasionally. And for the most part, that usually takes the form of some kind of domain modeling, whether it's based on database tables or just domain objects. And sometimes I will try and draw them out and then specify the relationships between them like, oh, you know, this one model talks to this other model in this particular way. And I'll define a relationship between them, which helps me think about them and how they interact. JOËL: I've found that even though for some things I can see it very vividly in my mind's eye, I struggle to then concretely translate that onto paper or digital paper if you will. It's almost like trying to, say, translate an emotion into words and that even though I feel like I see a visual picture, I can't reproduce it by drawing necessarily. EEBS: It's interesting you brought up feeling because a lot of the times, I have this gut feeling about a mental model, like whether I think it is correct or not. And sometimes I have this uneasy feeling of, like, that doesn't feel right to me, but it's hard to articulate why. And I think sometimes that's when I have to pull out something physical, start making those relations, start connecting things. And that's when I might uncover, like, oh, this feels odd because I have a circle here or a cycle or something. Or I've sort of represented the truth of something in two different places. Do you have any techniques for getting it out of your head and into something physical that you could share with someone else, maybe it's text or a picture? JOËL: I think I do struggle with that conversion sometimes. Practice definitely helps. I think maybe there is a metaphor here between converting these, let's call them, pictures that I see in my mind's eye and then drawing diagrams with trying to take feelings and expressing them in words. In the same way that, maybe I might have some feelings, and then I want to journal how I feel, and I struggle to express that. But finding a way to express that gives me a certain amount of precision and a more concrete thing. In the same way, these things that flash in front of my mind's eye, if I can take the time to put them on paper, they're now more real. They're more concrete. I think you can probe the edges, the ways that it kind of falls apart more easily. EEBS: Yeah, that makes a lot of sense. There's a lot of value in writing that down and going through those details in a methodical way because oftentimes, you'll catch inconsistencies, or you'll find better ways to describe it. And being able to share your mental model with someone else is often...well, it can be really tricky. And I think that's why it's important to go through and maybe find a common medium that you can share because I can't see into your brain. You can't see into mine. But if we can share our mental models, then hopefully, we have a better chance of agreeing on the solution or finding inconsistencies. JOËL: Exactly. I think, in many ways, there are almost multiple layers of mental models and that you might have an abstraction or a metaphor for a concept that you're working with separate from the diagram. And then the diagram is yet another metaphor, but now we're going geometric to represent a broader idea. EEBS: Yeah. Are there any other ways that you take that picture from your mind's eye besides written documents or conversations? Do you use any diagramming tools that specifically help with that? Or is it just kind of free-form? JOËL: I do a mix. I am a big fan of draw.io, which allows you to just free-hand or pull shapes together, things like that. There are some more structured tools that I will use. I'll use Mermaid.js. EEBS: Yeah, I've been using that a lot too. JOËL: Yeah, that's great. I've been digging into more structured diagrams recently, particularly the idea of graphs, directed graphs. And those have interesting properties. EEBS: Can you share a little more detail about what you mean? JOËL: So a graph in the computer science sense is a bunch of nodes. They are typically represented as circles and then edges which are the connections between them. A directed graph is now there's an arrow pointing in a particular direction. A really interesting property that you can have with directed graphs is whether or not they include cycles. So can you only by following the arrows effectively create a loop? Or will the arrows always lead you to some kind of terminal node? EEBS: Gotcha. Is that a directed acyclic graph? JOËL: If there are no cycles, yes, it is a directed acyclic graph or DAG, as you'll often see it abbreviated. EEBS: [laughs] How do you relate that graph to code? And what benefits do you get from expressing it that way? JOËL: So this shows up in a lot of places. And I'd even say that thinking of certain aspects of my code as a graph and a potentially directed acyclic graph is itself a mental model or a metaphor that helps bring clarity to the way I think about things. So, for example, code, you know, you invoke some main function at some point to call the code, and then that's going to call out some other functions, which call out some other functions, and so on. You may have heard that referred to as a call graph. But that is a graph of calls. There might be cycles in there for co-recursive functions and things like that. But that is one way you can then sift through and analyze how control flow or how logic flows through your application is through a function graph. You mentioned earlier the idea of objects and how they're connected to each other. That's an object graph. EEBS: Right. Recently, I had to work through a state transition problem where a customer has some billing, and they can go through many different states, whether it's active, or canceled, or past due, those sorts of things. And so actually, I reached for Mermaid.js and built a graph of, okay, they start here in this empty state. And then they subscribe, which then they become active. They might cancel their subscription, which moves them to a different state. And by listing out all the states and the transitions between them, it helped me to understand what methods I might need to define on which objects in order to allow those transitions to happen and what checks I might need to make before allowing those transitions depending on the state of the system. JOËL: I'm hearing the keywords states and transitions. And that's making me think of finite-state machines. Are you drawing a finite-state machine graph or something a bit more free-handed? EEBS: It's a bit more of free-handed. I don't think I've actually drawn out a state machine since college but just representing the different states as different boxes and the transitions that are possible from those states. I mean, I guess that kind of is a state machine in some way. So graphs are great visual approaches. Are there any non-visual approaches that you take? JOËL: That's a great question because not all mental models have to be visual. I think the power of a mental model exists in a metaphor. And one that's kind of broad but that I've applied to a lot of different areas is the general idea of something being parallel or in series. I think I first came across this concept talking about electric circuits. And are we talking about two little light bulbs that are in parallel, and if the electricity to one is cut, the other one still lights up? Or are they chained together in series? EEBS: Yeah, like my LEDs. JOËL: Exactly, going back to Arduino, but it can also be applied to a bunch of other things. We can talk about code being in parallel or in series. We can talk about work being in parallel or in series. Interestingly, I took that mental model as a sort of quick shortcut when I was digging into some functional programming ideas. Monads and applicatives are the fancy terms here. EEBS: Oh boy, I'm ready. JOËL: In general, and there's a hefty asterisk here, I think of monads as being serial, so you're chaining something; one thing happens, then another. So you can think of, for example, chaining promises in JavaScript, promise one, then promise two, as opposed to applicatives which are parallel. So you might think of maybe zipping two lists or two arrays in Ruby. The two arrays, there are no dependencies between the two of them. They get processed side by side as you're traversing both of them together. EEBS: Interesting. I've heard the term monad a lot, but I haven't heard the term applicative. Are there any other details you can share about them and what makes them different or how they might be seen in our code? JOËL: I think that the key difference is that distinction in how they're processed. Applicatives are a way of combining two independent, let's call them data sources, and then you find a way to combine them together. So it could be two independent arrays, and you're zipping through them. It might be two independent HTTP requests, and they can both fire in parallel. But then you want to combine their outputs. So you say wait until both are successful and then combine their output. EEBS: Oh, okay, gotcha. JOËL: It could even be nullable values. So you say do this thing if both values are present. But you're not...the value of one or the fact that one is null or not is not dependent on whether the other one is null or not. They're independently null or not as opposed to something...Monads are, again, a different way of combining. You might call them data sources or operations. But in this case, there is a clear dependency one, and then its output influences the next one. You might say check the value is null or present or not. And then, if it is present, take that value and then put it as the input of my next operation. And then, if it is null or not, do another thing. See, now you have a sort of chain. EEBS: Where do you see these chains happening in code? Or is it everywhere? JOËL: Once you know that pattern which, again, could be thought of as another mental model, you start seeing it everywhere. So promises in JavaScript chaining together that's effectively monads. Don't @ me, all the functional programming people. EEBS: [laughs] JOËL: I know that's not quite true. Anything dealing with multiple operations that could succeed or fail depending on, again, whether you're treating them as dependent or independent, that's probably going to look very similar to either monad or applicative. EEBS: So the first thing that actually comes to mind here is things like background jobs. Using Sidekiq or Resque or other job processors, you can have a queue of jobs that need to be executed, and they might need to run in serial, or potentially you have multiple workers pulling from a single queue, and thus the work is happening in parallel. Is that a reasonable analogy? JOËL: I think it's good for the serial versus parallel, but it's not necessarily a good analogy for understanding monads and applicatives. EEBS: Gotcha. JOËL: So with two workers, you can process a queue in parallel, and a bunch of things happen. EEBS: But there's not necessarily anything that is bringing those two workers together to produce a single output. JOËL: Yes. And there's no dependency between the tasks in the queue. EEBS: Right, right, gotcha. JOËL: So if you have a task that says execute this task and then only if this task succeeds, then do the second task, now you've created a dependency. And you couldn't process that in parallel because if task one, which has to be executed first, is executed by worker one, task two should not get processed unless task one is successful. You can't just say, oh, I've got another worker free. I haven't processed task two because it's waiting to know does task one succeed. EEBS: Right. So an example in code would be a user creates a new order. And when they create a new order, we send them a confirmation email. That would be an example of that happening in serial or a monad-like thing. [chuckle] JOËL: Yes, I found that thinking of things as serial or parallel is a good shortcut for thinking about monads and applicatives. I don't know that the reverse is necessarily true. They don't necessarily transfer one-to-one with each other. And maybe that's a danger of mental models, right? You find a mental model that describes a situation, and then you try to reverse it, and then you make false assumptions about the world. MID-ROLL AD: Debugging errors can be a developer’s worst nightmare...but it doesn’t have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake’s debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake’s lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! JOËL: Another mental model that is not necessarily visual that I like actually comes from the video game community, and that's thinking of skill ceilings and skill floors. So in, I think, particularly the MOBA Community, that's a Multiplayer Online Battle Arena, they'll talk about characters as having a high skill floor or a low skill ceiling. And generally, what that means, and again, the meaning varies a little bit by community, is that a character with a low-skill floor is an easily accessible character. They might not have a lot of skill shots, like, you press a button, and things happen around your character. You don't need to aim, things like that. A high skill ceiling means that there's a lot of room for you to grow, and as you get more skilled, you can get significantly better with that character. EEBS: Gotcha. So the opportunity is greater with a higher skill ceiling. JOËL: Correct. And depending on how the character is set up, you might have a very narrow range that could be in the low range where it has a low skill floor and a low skill ceiling, which means that the character is easy to learn. But once you've learned it, there's not really a lot you can do with it. It's a fairly basic character. So getting better at the game is not necessarily going to make you that much more impactful. And then you could have one that's the opposite that is high both skill floor and skill ceiling where a character is very hard to learn. But once you learn it, that's kind of all there is to it. And then you might have one that has a large range somewhere; maybe it's easy to learn, but it's hard to master, or there's a lot of room for growth. And so, taking this framework for analyzing characters and video games, I think we can apply that to technology in general. This could be language design. This could be just API design. And you might say, well, I want this to be very accessible. People can jump in very easily. You might say I want this to be very powerful and have a lot of high-end features that make your power users very happy and very productive. EEBS: That's interesting. When you first were talking about it, I was actually less thinking about it from a user's perspective of what maybe they could do in the application but potentially from the standpoint of a developer writing the system itself. One of the pieces I always come back to in software development is that change is inevitable. And so, making something easy to change often pays great benefits down the road. And so I wonder how that fits into this idea of a low skill ceiling or a high skill ceiling in terms of perhaps flexibility or being decoupled such that you can take one idea and easily extend it or easily get more from it than you originally set out to build. JOËL: There's often a trade-off. So you make something easy to change. It's highly decoupled. But you maybe introduce more indirection to the system. So while it's easier to change one single piece, it's harder to understand the system as a whole. EEBS: Yeah, that's true. And sometimes, you bake in assumptions that you make about the future, which turn out not to be true. JOËL: [laughs] Yes, that is definitely something I'm guilty of. EEBS: I think we all are. JOËL: One thing that I find interesting is as you evolve the design of an architecture pattern, a system, a whole language, you might want to move one of those if I think of them like two independent sliders on a one-dimensional scale. So maybe you want to move the upper boundary a little bit and say I want a higher skill ceiling for this, but they don't actually move completely independently. So introducing some advanced features might inadvertently also raise the skill floor. And conversely, making the language super accessible so that it has a low-skill floor, you might have to decide I will not introduce certain features. EEBS: One thing I wanted to ask you about is, do you view different languages as having different skill floors and ceilings? And, you know, I love Ruby. I know you love Element. I've played with Element. It's been a great learning tool for me. How do you view those two languages in terms of skill ceilings and skill floors in terms of, I guess, what you can do with them? JOËL: That's a great question. And I think you can definitely apply that to languages. Admittedly, I think you could probably start a lot of flame wars with that. EEBS: [chuckles] Let's not do that. JOËL: I wrote an article a while back where I applied that mental model to look at the F# programming language. And there was a debate in that community about certain features to add and whether they would allow advanced programming but potentially at the cost of accessibility to newer members of the community and how to balance those. And so I thought, hey, let's throw this video game metaphor at the problem and talk about it through that lens. EEBS: That's really cool. Did you draw any conclusions, or was it as a way to start a conversation? JOËL: It is a way to start a conversation. I don't think there is a single correct or best distribution of your skill, ceiling, and floor. It has to match the goals you set out for your project. Just like in games, people love to rank which characters are best and not. And sometimes you can show that, in general, this character is better. But oftentimes, in a balanced game, you can talk about this character being easier to get started with or this character working very well if you're a pro. But the fact that you have a higher or lower skill ceiling or floor doesn't necessarily make the character better or worse. EEBS: So, this conversation about differing mental models, I think I hadn't realized that there can be so many different types of mental models. And some things that I do in my thinking I haven't classified as a mental model. But now that you bring it up, I think one that I think about fairly often is this idea of two objects that are collaborators and reaching into the internals of one of those objects from the other object. So A and B are two separate things. And if A reaches into B's bucket and messes with the state of B, I view that as sort of a bad practice. You're not really adhering to maybe the public API that that object is exposing. You're kind of reaching in and going around behind its back and changing some stuff that it may not expect. JOËL: Would you refer to that maybe as tight coupling? EEBS: Yeah, it's definitely tight coupling. It's not just tightly coupled; it's almost worse than that. It's almost like going behind somebody's back and making a change without them knowing. And so when I see that in code or when I write code that does that, I have this really intense desire to separate that and to say, no, no, you can't go in and update this record directly in the database. You have to send it a message and say, "Hey, I would like you to be aware of something," and then it goes and changes its own internal state as a response to that. And so I have this very vivid sort of mental feeling of it being wrong, of it being like, I'm being sneaky, or I'm not being gracious to the person I'm interacting with as though I were one of these objects. JOËL: That's fascinating. You've practically anthropomorphized these objects. EEBS: I do. I view them as little people. JOËL: You describe this interaction as going behind someone's back. That is the thing that I, a person, do to someone else. It's not a function making a direct call. And yet, it's such a strong...we use a social mental model to talk about objects and interactions. EEBS: Yeah, I almost want them to be friends. And I think that applies to real-life relationships, right? If you have a nice dialogue back and forth, there's an understanding. There's commonality that you can find. But if I were to go do something behind your back without chatting with you about it first, you might not be so happy with me. JOËL: I'd feel betrayed. EEBS: Right. JOËL: I feel like there's probably a really fun conference talk to be done about that. We often use that metaphor; I think when talking about objects sort of subconsciously but making it explicit and just being, hey, let's talk about these objects as if they were people. Why don't we want to do this? Because this one here is betraying the other object there. This one here is being impolite. EEBS: We could have two people get on stage and talk to each other. And I might then go and reach in your pocket and pull out some change without you knowing, and you might be upset with me. JOËL: That would be great. Get a little skit going up on stage. Or even if you're artistically inclined, you could probably draw some really fun little characters to illustrate this. EEBS: That would be really cool. I, unfortunately, don't have the artistic talent to do that. JOËL: Well, free conference talk idea to all listeners of the podcast. I expect to see this for RailsConf 2023, maybe. EEBS: I'll be looking for it. So I've shared a mental model that I didn't really know was a mental model. Are there other mental models that you want to share that I may not be thinking of? JOËL: Here's one that I've just come to realize recently that I'm actually quite excited about: when you think about the word refactoring, how would you describe that idea? EEBS: Well, refactoring to me is changing the implementation without changing the behavior. JOËL: Yes, I think that is the classical definition. You should be able to change the implementation of a method, and the tests without changing are still green after you've done that. EEBS: I guess, mentally, I think about that as perhaps drawing a box around some of the objects that are floating in my mind's eye, rearranging how they exist within that box, and then the box dissolves. And the tests still pass, but the structure of the objects or the code has changed in my mind. JOËL: I love that you immediately went to a visual approach there. And I think I have something similar, but I'm coming at it from a slightly more domain modeling perspective. So thinking maybe less from an individual method approach but looking at maybe a larger system, what you're trying to do is use code to describe some version of reality. So it might be a business process that you have. It might be trying to describe some aspect of your customer's life that you're trying to automate for them. Oftentimes, this thing you're trying to describe in code terms is going to be a simplification because life has a ton of edge cases, and many of them we don't care about. So if we go with a visual metaphor here, you're trying to draw some kind of shape using only straight lines to approximate some weird curve. And so, let's say you draw something with only four lines. It's really simple, how you have a diamond. That's the shape you're trying to create. And then you're going to fill it in with little other shapes that approximate a diamond. And those are your different models and functions and all the other components that we use to build software. At some point, your understanding of the underlying reality might change. Maybe you need more precision, or maybe the actual feature requirements have changed. The thing you're trying to approximate with your code is not a diamond. Maybe you've added a few more sides to it. It's a pentagon. So we've gone from four sides to five. And the little components, and modules, and things that you have there approximate that diamond work. They still mostly approximate your pentagon, but it's really clunky because the initial design was to approximate something else. They were really good for fitting in really tightly and being very loosely coupled to each other when we were trying to do a diamond, but then they don't work as well in the pentagon. EEBS: So maybe some of the internal shapes need to change or adjust to fill the space that the pentagon has now created. JOËL: To fill the space or maybe even just to fill it in a way that's less clunky. And so the idea here in this metaphor is that the reality we're targeting in software is always changing. And so the underlying reality changes, and so we're changing that shape that we're creating all the time. But also, we're getting more precision as we decide; oh, we care about this edge case now. We didn't in version one, and so as part of that, we're constantly having to take the modules that maybe were very well designed initially but then restructure them to fit the new requirements because now there's a fourth object coming in, and it's kind of clunky with our current configuration. EEBS: That's interesting. One of the first things that jumps to mind is that maybe there are better ways or worse ways to do that refactoring to fit that new shape. Do you think there's any truth to that in the sense that you might initially design a system that perfectly fits that diamond or very closely fits that diamond but then as it changes to a pentagon, do you need to simply add a new piece to fill in that empty space? Or do you need to restructure everything within the diamond now to fit the shape of the pentagon? JOËL: Oftentimes, you do need to restructure. And I think there's this wonderful little phrase from; I believe it's Kent Beck that says, "Make the change easy, and then make the easy change." EEBS: Yep. JOËL: And so, to me, that makes the change easy is that initial restructuring that you need to do of those first shapes so that you can finally bring in the new one. EEBS: Oh, that's a cool visual. I immediately can imagine the pieces in the pentagon moving around to make space for a new piece that you need to now bring in. And that movement of all those pieces can be really difficult. Have you ever played that game where it's a square, and you're trying to get a ship out of a port, but there's a whole bunch of other ships, and you can only move them left and right and up and down? And you can do that. And that's what I'm picturing right now is moving shapes within that pentagon to then make space for either a new shape or to allow a shape to escape that is no longer relevant. JOËL: I played a version of that that had cars, cars, and trucks. EEBS: Gotcha. Yeah, I think I played that too. JOËL: That would also be a fun conference talk, right? Like, start with that game as your initial metaphor. And then you use that as a way to talk about refactoring. EEBS: That would be really cool. JOËL: I would watch that talk. To anybody listening who wants to give that talk, I want to see you at RailsConf 2023. EEBS: [laughs] Are we just a talk factory now? [laughter] JOËL: I love talk ideas. Maybe this should become a segment. Just have Eebs come in for five minutes once a month and give us a talk idea. It could even be fun to see a talk idea that multiple people implemented differently. EEBS: That would be really cool, actually. I always get nervous about giving talks or being on podcasts like this one. I would love to be the person that gets to sit there and throw out random ideas and have other people fulfill my dreams. JOËL: Well, thank you so much, Eebs, for joining us to talk about mental models. And to all of our listeners, I'd love to hear about what mental models you find are helpful, and so please share them with us. On Twitter, you can reach us at @_bikeshed. EEBS: Thanks for having me, JOËL. This has been super fun. JOËL: And on that note, let's wrap up. The show notes for this episode can be found at bikeshed.fm. This show is produced and edited by Mandy Moore. If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. If you have any feedback, you can reach us at @_bikeshed or reach me at @joelquen on Twitter or at hosts@bikeshed.fm via email. Thank you so much for listening to The Bike Shed, and we'll see you next week. Byeeeeeee!!!!!! 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:Airbrake: Deploy fearlessly and fix bugs faster with Airbrake Error & Performance Monitoring. Airbrake notifiers are available for all major programming languages and frameworks, and install in minutes, with an open-source SDK-based install and near-zero technical debt. Spend less time tracking down bugs and more time developing. Visit Frictionless error monitoring and performance insight for your app stack.Support The Bike Shed
undefined
Aug 30, 2022 • 32min

352: Case Expressions

As developers, we care a lot about code quality. How do we know how good is good enough? When do we stop improving code? Alternatively, when working on code that's really bad, how much do you improve it before calling it a day? thoughtbot's Stephanie Minn joins Joël to chat about this and case expressions: We recently discussed these as part of thoughtbot's RubyScience reading group. Are case expressions bad? Are they equivalent to multi-way conditionals? When do you use polymorphism? This episode is brought to you by Airbrake. Visit Frictionless error monitoring and performance insight for your app stack. RubyConf 2022 RubyConf Mini Stephanie's talk at RubyConf 2021 WNB.rb Joël's RailsConf 2022 talk Ruby Science older episode on wizards TCR Transcript: JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. And we're here to share a little bit about what we've learned along the way. Today, I'm joined by a fellow thoughtboter, Stephanie Minn. STEPHANIE: Hi, Joël. JOËL: Welcome to the show. STEPHANIE: Thanks. Happy to be here. JOËL: Stephanie, what's new in your world? STEPHANIE: Thanks for asking. I've been working on writing a CFP for RubyConf, which you have been plugging internally at thoughtbot. I wasn't really sure if I wanted to do it, and then I found out about RubyConf Mini, which is happening as an alternative to the main conference in Houston. And that got me really excited to have some more options and just got me thinking about what I might have sitting on the back-burner that I might want to give a talk about. JOËL: That's really exciting. I'm curious, what is your process for coming up with an idea for a talk? STEPHANIE: I think they come in seasons, ideas, for me, so not even necessarily when it's conference time. But if something has been sticking in my brain for a really long time, especially as it relates to processes on teams that I'm on or my day-to-day workflow, and it's something that I keep coming back to and trying to figure out what it is about it that my brain wants to work through a process, that usually tips me off that this might be something that other people are thinking about or working through. In this case, I am planning to write a CFP about pair programming. And yeah, it's something that I've been thinking about doing for a while, and it seems kind of an evergreen topic. So I thought I would pull it out for this conference. And if it doesn't end up getting accepted, I can always resubmit again in the future. JOËL: I love that. So it sounds like you have a note or maybe an actual written notepad somewhere where you just, over the course of the year, build up ideas, and then you take a look at that when conference time comes around. STEPHANIE: Yeah, that's about it. I have just a very long-running note of half-formed thoughts. And then, when I give myself time to really reflect on how things have been going at work, I usually revisit it, and if any of them still resonate or stand out to me, I will go through and try to see if there's any content to come out of that. What about you? I know you are an extensive note-taker and ideas blogger. JOËL: I have to say I really like your approach of gathering ideas throughout the year. I've worked with many people who would love to give a talk at a conference as a professional goal but then get stuck in the I don't have any ideas. I don't know what I would talk about. And most people have a thing they could talk about. They just don't know it. And it sounds like you've done a really great job of gathering this info throughout the year so that when the time does come, you don't just freeze. You're like, no, here are the 10-20 things that I experienced or that I am an expert in or that I would love to share. And maybe there are two or three in there that would be very well-fitted for the conference you're looking at. So I love that idea. I have not done that myself personally, but maybe I should start doing that. STEPHANIE: What about you, Joël? What's up in your world? JOËL: So I've also been thinking a lot about RubyConf coming up, working on a few ideas for myself. And then, there are a few people that have reached out to me to help them craft ideas or get a little bit of feedback on their proposal. So I've been doing a lot of proposal reviews as well. STEPHANIE: What do you enjoy about reviewing other people's proposals? JOËL: I think for many people speaking at a conference is a really big, ambitious professional goal, and so helping people achieve that is really fulfilling for me. Some people might feel almost inadequate or unprepared. But because I know them, I know they've got good things to share. And so it's almost seeing the greatness in them that they don't quite see yet or that they don't feel confident about. And so being able to see that in their proposal and say, "Oh, there’s a core of a great idea right here, tweak it a little bit, and that'll give you a slightly better chance with the committee and help you towards that path of being on stage for the first time," is really exciting. STEPHANIE: I spoke at RubyConf last year, in 2021, virtually. And I remember that was my first time speaking at a conference. And I was worried that my talk was not super hardcore, technical enough. But my goal for my talk was to aim it towards other developers like me who are maybe mid-level and wanting to reach this whole audience of people who are attending these conferences to learn and to level up who aren't necessarily super senior experienced developers. And it was a really great experience. People seemed to really resonate with that. So I really encourage folks to speak about things that are resonating with them at whatever point in their careers because there are so many people out there who are probably in the same boat and want to hear what you have to say. JOËL: Absolutely. I'm curious, now that you have experienced the full cycle at least once, from ideas to crafting a submission, to getting accepted, preparing a talk, delivering the talk, and then recovering from that, what are maybe some lessons learned or some things you weren't expecting the first time you went into that that now you do know going into another cycle? STEPHANIE: Yeah, the power of community; I had a lot of support from WNB.rb, a woman and non-binary Ruby community. We crafted our CFPs together and then practiced our talks together and had a working group that met every couple of weeks to give feedback on our talks as we were working on them. And it was really awesome to have that accountability, to have that support, people to tell you that your talk is good and give you a thumbs-up. And I really want to continue investing in my community that way. And I really appreciate you asking this question because I guess I do have things I've learned and would want to share that with other people in my community, and yeah, just continue to encourage folks who may not have been traditionally encouraged to speak at conferences. JOËL: Community is so powerful. Even though I've spoken at multiple conferences, I still get nervous about my talks. I have a lot of self-doubt about whether my topic is good, whether I'm sharing it in a way that's going to be impactful. And I had a magical experience at RailsConf this year where a group of us were at a hotel lobby practicing our talks the night before. And I was just still so unsure about my talk. And the feedback that I got there gave me a huge boost of confidence that I was able to ride into the next day and give a talk that I think turned out rather well. But honestly, that was my favorite moment of the conference was 11:30 p.m., a group of people in the hotel lobby taking turns practicing their talks. STEPHANIE: Yeah, I love that. MID-ROLL AD: Debugging errors can be a developer’s worst nightmare...but it doesn’t have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake’s debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake’s lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! JOËL: One thing we've been doing recently at thoughtbot is every other week book club discussion, and we've been looking through the book Ruby Science published by thoughtbot. Every week, we'll have someone who is a facilitator, who has done the reading and has prepared some questions for the group. And you recently facilitated a session on the topic of CASE expressions and why they might be a code smell. That sounds like a really controversial statement. How did you approach that topic? STEPHANIE: It's funny because I was looking at the upcoming chapters to pick a topic to facilitate for this book club, and CASE statements stood out to me because I was like, oh, I know what that is; that will be easy. [laughs] But it turned out to be a bit meatier than I thought it was going to be. I'd say that I didn't really consider them a code smell until I read the chapter of Ruby Science talking about them. So I was a bit surprised because they seem so common, which is probably also why I thought it would be an easy topic. JOËL: Would you say that reading the book or that particular chapter changed your mind? STEPHANIE: I think it did only because I hadn't necessarily given them a second thought or thought of them more deeply in that way. I think that, at least in my experience, you encounter CASE expressions pretty early in your career, and you think they're a cool tool for making your conditionals look a bit nicer. And it takes probably a bit more experience, a little bit more pain using them or trying to extend them that you start to have a bit of a more higher level awareness of what might be problematic about a CASE expression. But the book club that I facilitated, we had a really engaging discussion where most folks agreed that it was a code smell but also said that it depends. JOËL: Classic consultants. STEPHANIE: Truly. One thing that someone said that was a really nice takeaway for me was that CASE expressions get a bad rap in object-oriented languages because there are typically other tools or options you can reach for that might be preferred. And someone else said that it's probably a sign that you might be doing too much in the method. JOËL: Hmm. You mentioned that there are some tools and things that might be preferred over CASE expressions. What are the common alternatives that people say you should use instead of a CASE expression? STEPHANIE: I think one simple solution that we discussed in the book club for more straightforward cases would be a hash lookup to use instead of checking for equality via CASE statement. Another solution we talked about was polymorphism, which I think might refer back to the idea of having a bit of a higher level understanding of abstractions in the codebase and what things might look like in the future, especially when you might not have too many conditionals yet in your CASE expression. Another thing that really stuck out to me in our book club discussion was another thoughtboter mentioned Sandi Metz’s 99 Bottles of OOP. And in that initial solution, she presents a CASE statement as the perfectly fine solution for now. And I thought that was really interesting because, in some cases, that might be all we know about the problem, and that is perfectly fine. What do you think about that? JOËL: I love the idea of starting simple. Don't try to start with abstraction, especially if you're doing test-driven development. You have a test, make it go green, use the simplest thing, use duplication, use all the dirty tricks. And then from there, now that you know I have a test that was red and this code makes it go green, now the question isn't how do I solve the problem? It's how do I improve the solution? So we've kind of separated those two steps out, and I really like that. STEPHANIE: Yeah, I remember you mentioned that you had refactored something into using a CASE statement. And I'm curious if you want to share more about that. JOËL: Oh boy, this was a "fun" problem. Fun is in air quotes, by the way. It was a multi-step form, AKA a wizard in a Rails app, where every step submitted to the same controller, and the controller was a huge mess. It had to handle submissions from four or five different forms, some of which shared fields. And it was this huge, deeply nested conditional thing that checked if this field is present in params, that probably means we're on step three, except if this other field is also present, then it probably means we're on step four. But if this Boolean flag in the database is set to false, we might be on a variation of step three. And because there was branching, potentially, it was an absolute mess. By looking at the code, you could never know what step of the processing you were on. What I did is instead of all of these nested if else conditions, I wrote a flat CASE expression that just said, if step one, do step one logic or process step one form. If step two, process step two form and so on. So it was nice and flat. I was able to reuse some parts of the work across by making private methods or other objects, things like that. But you could easily tell in any part of the code what step you were processing. Which means if you get a new feature from the client that says, "Can you modify the behavior on step four?" Now you actually know where to go to. You go to this controller; you find the big CASE expression. You find the branch that says, "If step four," and then you drill down from there. STEPHANIE: So after refactoring that into a flat structure, did you find the code more readable? Did other folks on the project think so too? JOËL: Yes, it was unanimously loved because this is the part of the code that everybody feared to touch. It was the most awful, gnarliest code. And a few of us had touched it, and so if you did the git blame, our names would show up, which meant that anytime anybody got stuck in that code, they would reach out to us and say, "Hey, you're the last one who touched it. Can you fix this for me?" And it was a big game of not it. Cleaning it up made this code accessible to everybody on the team. STEPHANIE: And why do you think a CASE statement was the right solution in this particular case? JOËL: I think if it's a multi-step form that maybe had seven steps in it, you clearly have seven branches that you're working with. And so hiding that behind nested conditions where you try to reuse each other's branches just muddied the waters. We have a seven-way branching path; let's be honest about it upfront and do a seven-way CASE expression. STEPHANIE: One thing that we didn't really talk about as much in our book club discussion was that CASE statements can be quite readable, especially for newer developers. And even though we all did think it was a bit of a code smell, I recently encountered on my client project in a code review someone saying that they preferred a CASE statement in that situation because it was easier for them to grok. I think that's a benefit worth considering before trying to do something fancier in some cases. And I'm curious what you think about that. JOËL: I strongly agree that a CASE expression is a great place to start, especially when you have actually more than two branches. Your logic could go one of n ways. I generally like to branch earlier than later in a lot of code. It's better in my mind to have a seven-way branch at the top of your decision tree and then just straight lines down than this constantly looping back and branching again and looping back, trying to force everything down a single path when it really doesn't want to be. STEPHANIE: So, in this case, did you know that you had those seven branching paths upfront, or did you have to tease that out? JOËL: I did not know from the code. Honestly, it would be very difficult to infer that from the code. But from the product, I knew this is a multi-step form with seven steps. And so I knew what the branches were from the product description. But no, it was almost impossible to infer that from the code. Long-time listeners of The Bike Shed may remember an older episode where Steph and Chris discussed multi-step forms and how best to approach them in Rails and also in JavaScript. And one thing that did come up is that an ideal way to work with a multi-step form in Rails is to have every step be its own controller. So you have a view, it submits to a controller, which renders another view or redirects to another view which submits to another controller. And that is the direction that we went with this multi-step form eventually. Once the single controller had a big CASE expression in it, we slowly started moving each branch out to its own controller. And now we had the step one controller, the step two controller, the step three controller, and so on. And I think that was probably the best solution in the end. But we had to go through the CASE expression just to know what was safe to move out. Interestingly, this refactor is effectively replacing a conditional with polymorphism because all of our controllers are controller objects. They respond to the same interface. And so this gets classic refactor that Ruby Science suggests, which is what we did and kind of what Steph and Chris recommended if you had the luxury of starting from scratch all those episodes ago. STEPHANIE: Nice, I'm glad it turned out that way and was a lot more manageable. JOËL: It's really interesting when you're working with a situation like that where you've got really messy code, and you can make some improvements. And it's like, how far do you go? Especially because there's usually a backlog of new features that the customer wants you to implement. So I'm curious for you, Stephanie, how do you know when you've gone far enough in improving code, either in a refactor step for your own code for a feature you're writing or maybe you're trying to take a break and say I'm going to take a little bit of time today to improve this area of the code. How do you know how good is good enough? STEPHANIE: That's an interesting question. I think I encounter that in a couple of ways, either in my own work when I am tasked with a feature, and I start getting into the code, and it stresses me out and leaves me a bit confused and not sure where to go to work on my feature. That is usually a signal that I might need to pay some attention first and make the change easy and then making the easy change. The other common thing that I have experienced on teams is we collectively feel the pain of an area of the codebase. And maybe we talk about it at a developer meeting, and all agree that, yeah, we really want to give this part of the code some love and add it to the backlog. But it's tough in that case because, like you said, there are a lot of new features that stakeholders want. And we as developers want to be over here taking care of our little codebase [laughs], making sure that it is healthy and it feels good to work with. JOËL: I feel like I don't just want my codebase healthy; I want it pristine. STEPHANIE: Ooh, pristine. What does that mean to you? JOËL: I want it perfect, nice, and shiny. And, of course, it's never that, which is why it's always tempting to toss out the old code and start over and do it right this time. That's not a good thing. You have to be able to live with the messiness of everyday life and the fact that, okay, here's an idea. I think if your codebase is perfect, you've put too much work into it. You've gone too far, and you're beyond that; when is good enough good enough? STEPHANIE: Whoa, that's a big statement. JOËL: [laughs] Feel free to disagree with me here. STEPHANIE: I guess I'm curious what perfect is in this case. JOËL: I think it's subjective for the developers who are writing it. But oftentimes, the ones who are looking for perfection go way too far in their quest for that. STEPHANIE: Way too far at the expense of things like business value or other things? JOËL: I think in two ways; one, you probably ended up overengineering things to try to make it so perfect. Your design needs to have some amount of flex in it for the unknown. It's okay to have some rough corners because it's going to change. And you're going to have to redo that corner next week anyway. So you need to not go all the way in making everything absolutely perfect. The other thing is that if you are putting in the effort to make everything perfect, at some point, you hit diminishing returns. And that's not worth your time from a business perspective or even on a personal project where you're just trying to ship things. At some point, you need to make actual progress. STEPHANIE: I'm curious if you mainly hold yourself to those very high standards or if you also think about that when reviewing other people's code. JOËL: So I mentioned earlier that I want my code to be pristine. I want to be clear, that's a bad thing. I do not actually hold myself to that standard. And I try not to hold other people to that standard, either. It's sort of tempering idealism with pragmatism. So being able to say, look, can we cut scope and focus on just one thing? Or does this fulfill the need that we have? And will it hurt us if we leave it like this and come back to it later? Or that question I asked you at the beginning, is this good enough? And maybe we can come back to it eventually. STEPHANIE: I really struggle with that question sometimes because, in some ways, people talk about software as a craft. And if we were building it in a vacuum, we could fine-tune and hone it until it's this beautiful, perfect, pristine thing. But because we write software for real things in the real world, we are constrained by the needs of our users, or the business, or just the purpose of building software is for folks to use it. And in that case, part of the job is evaluating trade-offs and deciding when is good enough. But sometimes, when I'm by myself working or coding for a little while, I do get sucked into wanting to make this the best that it could be just for my own personal fulfillment and joy. And I have to pull myself out of it sometimes and take a step back and be like, is this good enough for now, good enough for other people to be able to understand, work with in the future? And sometimes, it also requires getting other people's input too. JOËL: That's really valuable. STEPHANIE: Yeah, the worst thing that could happen is squirreling away with your code, and then you emerge with something that was totally not what was asked for. [laughs] JOËL: Especially on a work project. On a personal project, it's often good to know why you're doing a thing. And so maybe you want to see how far you can get away with pushing a particular metric, whether it's you want to go extreme on the decoupling or 100% TDD, or maybe you want to try something like test && commit || revert which is a development methodology. And those are all great as learning experiments, and then you go as deep as you want. I'm going to make another hot take here, and again, feel free to tell me I'm wrong. I'm going to say that on your own personal projects, if you pursue perfection, even when it's not for work, pursuing perfection on personal projects dooms them to join the others on the pile of uncompleted projects on your GitHub. STEPHANIE: That is an interesting take. I think it depends on the goal of your personal project because I personally like to have my projects be a bit of a sandbox, and I have no expectations that they will end up being anything that other people would necessarily look at, even though I guess they just end up public on my GitHub and are just sitting there in a weird, unfinished state. But yeah, I like to use them as an opportunity to, like you said, practice those concepts that I am really excited to explore but might not necessarily have the opportunity to on whatever client project I'm currently working on. And sometimes, I end up just scrapping it, but the exercise itself was valuable for me. I'm curious, though, what types of personal projects you have that lead you to have that opinion. JOËL: I think the way I use personal projects is very similar to you in that they're generally for my own personal growth and entertainment. It's about the journey, not the destination. So I generally have no intention of making this a thing that other people will use. It's typically a way to try out a technique, or a concept, or an idea. And so, for those, going really far on a performance or quality metric can be the goal. And that's completely okay with the knowledge that I probably will not complete or ship this project. I've done a few others where I've done the opposite. I've joined Game Jam events where you typically have a hard deadline. This could be a longer one, like maybe a month or as short as a day or a weekend, and you have to build and ship something within that deadline. And then you have to really make some pragmatic choices. STEPHANIE: Yeah, that sounds like a lot of pressure. I don't know if I would necessarily thrive in that kind of environment. I really like to spend a lot of time thinking about my code and looking over it again, sometimes to the point where I might be a little bit too precious about it. I was reflecting on this recently, and I thought about back when I was earlier in my career and didn't have any idea of what clean or good code was or looked like. And I would just write the code that would make my future work and just put it up for review. And I was very blissfully naive, I think, at that point in my career where I wasn't self-conscious about it in any way. And I think I'm trying to find a good middle ground between being comfortable with whatever comes out when I do some work or write some code while also having more knowledge and experience being able to revisit it and give it a deeper look after some space and feeling good about it without spending too much precious time on it. JOËL: Yeah, it's that classic consulting; it depends. Learn to balance code quality idealism versus the pragmatic reality of your goal, which is I want to ship something, both on your personal project and at work. That perfect code is useless if you can't ship it for contexts where you actually care about shipping. And on that note, let's wrap up. The show notes for this episode can be found at bikeshed.fm. This show is produced and edited by Mandy Moore. If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. If you have any feedback, you can reach us at @_bikeshed or reach me at @joelquen on Twitter or at hosts@bikeshed.fm via email. Thank you so much for listening to The Bike Shed, and we'll see you next week. Byeeeeeee!!!!! 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:Airbrake: Deploy fearlessly and fix bugs faster with Airbrake Error & Performance Monitoring. Airbrake notifiers are available for all major programming languages and frameworks, and install in minutes, with an open-source SDK-based install and near-zero technical debt. Spend less time tracking down bugs and more time developing. Visit Frictionless error monitoring and performance insight for your app stack.Support The Bike Shed
undefined
Aug 23, 2022 • 37min

351: Learning in Public

It's Joël's first episode as host of The Bike Shed! 👋 Joël has fellow thoughtbotter Steve Polito join him to talk about the benefits and drawbacks of "learning in public" and how there are many, many different ways to do it. This episode is brought to you by Airbrake. Visit Frictionless error monitoring and performance insight for your app stack. Transcript: JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot. I'm Joël Quenneville. And I'm joined today by fellow thoughtboter, Steve Polito. STEVE: Hey, Joël. Thanks for having me; excited to be here. And congrats again on the new hosting gig. JOËL: It's exciting to record with my first guest, and I'm excited that you get to be a part of this. And together, Steve and I are here to share a little bit of what we've learned along the way. So, Steve, what's new in your world? STEVE: Well, on the professional side of things, I've been working on a Rails backend application that connects to a React frontend. And specifically, it's in the healthcare space. My biggest, I guess, struggle but also [laughs] thing that I've learned the most from this project is working with an inconsistent API can be very challenging. And that's been the consistent theme with this project. But from that, I'm learning a lot. Because prior to this, I'd done a lot of work with just traditional CRUD apps where it's just all-encompassed in the Rails application. So you're kind of in control of everything. This is my first time where we're very much dependent on a third-party API. I'm learning a lot, but it can be challenging at times. But we've gotten in a space now where it's a lot more predictable, and therefore, working with it is easier. That's on the professional side of things. Personal side of things, I, for whatever reason, decided to run a marathon in September, which means all of the training has to happen in the heat of the summer. I live in New England, and it's been unbearably hot the past two or three weeks, which means training has been unbearable. [laughs] JOËL: Ouch. STEVE: Well, I mean, that's what I get for signing up for a marathon at the end of the summer. So I look forward to just working with the unreliable API versus [laughs] doing this right now. That's what's going on with me. What's going on in your world, Joël? JOËL: For long-time listeners of the podcast, they'll know that former host, Steph Viccari, has been working on a slow test suite. And part of that work has been converting some old Test::Unit tests over to RSpec. I've been working on the same project with her, and so the saga continues. One of the really frustrating aspects of this work has been the Test::Unit tests rely a lot on fixtures which are just full of mystery guests. The fixtures that are just loaded at the top of the file refer to a few thousand records in the database, most of which are not relevant to the test that I'm trying to convert over. The problem is that I don't know which ten records, you know, which two users out of the 100 defined in the fixture file are relevant. They're not referenced directly anywhere in the test. But if the RSpec conversion that I do fails, it will break because some user is not present in the database. And so I need to reverse engineer the code and figure out what is missing, which user record is just assumed to be in the database. STEVE: Yeah, that sounds frustrating. Honestly, until working at thoughtbot, I didn't quite understand the concept of mystery guest. Because when I learned Rails, I just did the Michael Hartl Rails Tutorial, which, in an effort to make it as easy as possible, he just kind of does vanilla Rails. So there's no Factory Bot or RSpec, for example, and it's all fixtures. And it works very well for teaching you how to build and test an application without getting bogged down with too many of the extra things that come along with that. So I always thought, okay, fixtures, cool, no big deal. Why does everyone always use Factory Bot?[laughs] Like, what problem is this solving? And I'm realizing now because I've run into this too, the issue that it’s solving is this mystery guest, so that's one of the issues that it's solving. And that's just one of those things that I didn't really appreciate until I would run up against it in a similar situation you're describing now where you're writing a test. It might even be a very simple test, right? Like five lines or something, and you're just expecting something trivial to happen. And it's failing, and it's failing for the wrong reason. The message is so cryptic. And you're just like, what is this thing talking about? It's like referencing something that has nothing to do with the test. And that pain right there is the pain of a mystery guest. I just didn't have a name for it until listening to these episodes. And now I can appreciate why you want to avoid that type of stuff and also why Factory Bot is helpful for that. JOËL: I think it's the kind of pain that tends to bite you more when you're modifying the tests later on than when you're writing them upfront. And since now, with the work that I'm currently doing, it's all modifying existing tests, I'm feeling this pain on a daily basis. Does that track with your experience as well? STEVE: Yeah, pretty much. And then what ends up happening is you're working on a feature, and the test fails for the wrong reason. And then you realize 30 other tests fail for the wrong reason. And then, before you know it, you've spent four hours going down a rabbit hole to clean up the fixtures, or the mystery guests, or the implied setup that might be shared across other tests. It's just such a momentum killer, first of all. You're in this headspace of like, okay, here's the feature I'm working on. Let's just bang this out real quick; no big deal. I want to go to lunch in a couple of minutes. [laughs] And then you're trying to fix this test because it's failing for the wrong reason. And then you keep pulling the string, and you're like, oh, okay, well, there must be a mystery guest or something, but that took like 20 minutes to figure out. And then you figure that part out but then maybe fixing that mystery guest involves either updating that particular fixture, which could then fan out and cause other tests to fail because it depended on that fixture to have certain properties. Or you have to create a new fixture. But if you create a new fixture, there's now an extra record in the database. And that could break other tests because they are maybe expecting there to be a certain set of users and other things. But that's just one of those things that early on, I would listen to episodes like this or hear about mystery guests, and I would be like, I just don't get what they're talking about. If you have a few fixtures, how is that so hard to keep straight in your head? And sure, at first, it's not a big deal if you have maybe two fixtures or something. But then it quickly just reaches an inflection point where either there's more than one person on your team, or you have to add more fixtures or whatever. And then it just reaches an inflection point where it's just not sustainable anymore. And that sounds like that's obviously the point at which this project is at, and that's where you're trying to rein it back in. JOËL: Yes. So it's definitely making the conversion from Test::Unit over to RSpec more difficult. I've been trying something a little bit clever to try to figure out what data is actually needed because that's my core problem. I have a Test::Unit test that doesn't define any initial setup data. It just assumes that data has been created by fixtures at some point. But there are thousands of records in the database. So which ones do I need to port over to this setup phase of my RSpec test? What I've been doing is hooking into Active Support notification and watching the records that get read from the database from the Test::Unit tests. And that can tell me, oh, it's these ten that this particular test is using. Those are the ones you're going to need to convert over to your setup block. STEVE: That's clever. I like that. So you were just looking at the logs essentially. Or did you have to do any puts statements or anything? Or was it just the default internal logging mechanism that Rails has under the hood? JOËL: The simple version of this would be to look at the logs, so tail the test log file. I'm trying to be a little bit fancier and hooking into Active Support notification, which is something built into Rails that allows you to just listen to certain events in the system and then do actions based off those events. So I can subscribe to any database read and then say call this block when a database read happens. And in that block, I can then update a stats object that, over the course of the test, will then tell me what objects have been read from the database. STEVE: Oh, okay. That's clever. I'm glad you shared that too. Based on this discussion of mystery guests, I feel like that's just a good use for that tool. I almost wonder if there's an opportunity not even to abstract that because that'd be too much work and overkill, but just, I don't know, make like a gist or something and just reference that for the future. Because I feel like this is the type of thing that other people are going to run up against...or maybe even a blog post or something because it's just like, if nothing else, it would be good for future Joël to be like, how did I do that again? Oh, yeah, here it is. Like, it's in this blog post I wrote six months ago. So I could just copy and paste the code snippet and call it a day. JOËL: It's funny you mention blog posts because we have a lot of these conversations internally at thoughtbot. And without fail, someone will eventually comment, "This is great content. You should turn it into a blog post," to the point where we now have an emoji reaction for you should make this into a blog post. STEVE: Right. That's what's really maybe special about the software industry is there's just a lot of knowledge share built into it just with open-source software, for example. I mean, that's already a form of knowledge share. It's not a blog post, but it's a form of knowledge share. And I just think getting into a habit of just sharing these little artifacts, big or small, whether it's a blog post or just a code snippet, is really helpful for a variety of reasons. But one, and in this case, to go back to the issue that you've been facing on the client work is you just explained...We talked about a lot of things; two of them were like, what's the mystery guest? That's helpful for some people to know because until very recently like I said, I didn't even really understand what the pains of mystery guests were. And then, we also talked about a potential solution to that. So a naive approach is tailing the logs, but then you took it a step further with that clever solution to use that notification object. And if we weren't recording this right now, that might be lost in the ether forever. Maybe the people you're working with on your team would know about it, but that would kind of be it. So I think there's an opportunity for you to maybe abstract that into like a code snippet or blog post or something and just store it away for later so that future Joël or another developer can learn from that. JOËL: That's a really good point, Steve. Creating public artifacts like that is a form of...I've heard it referred to as learning in public before. And that's actually a topic that I think you've really demonstrated mastery of. You are great at sharing the things you've learned or even the questions you have with your colleagues, and the team at thoughtbot, and the broader developer community. What was your journey into starting to share in public like this? Because I know it can be really intimidating, especially for someone who's early in their career. STEVE: Yeah, that's a good question. So a very brief background on my career history is I'm not classically trained, so to speak, and I'm doing air quotes for those listening. When I say, I'm not classically trained, what I mean is I went to school for graphic design. And there was some overlap with web design, obviously. But I ended my collegiate career really just knowing how to use Dreamweaver and knowing a little bit about HTML and CSS and barely anything about JavaScript, and I didn't know anything about server-side languages. That was my base. And I was fortunate enough to get a job at a small WordPress agency. I got really good at understanding WordPress and how to configure a website and then making it look like the Photoshop document. JOËL: There's a shocking amount of the web that runs on WordPress. STEVE: It's a huge amount. And what's nice is that it doesn't...as you just heard, I didn't have a lot of experience with making production websites. So WordPress made it easy enough for me to get my feet wet. But I would run into a lot of problems. And I was the only developer at this agency, so I couldn't turn to my co-worker and say, "Hey, can you take a look at this real quick?" It was just me and Stack Overflow. That was it. The reason I'm saying this is because Stack Overflow and being the only person at the agency forced me to learn in public but from a different mindset. I wasn't necessarily learning in public; I was desperately trying to solve a problem by the end of the day. And it just happened to be in public because I would have to either go on Google or Stack Overflow or forums to find the answer. JOËL: So were you asking questions on these sites then? Like, you were going into a chat room and asking questions or going to Stack Overflow and asking questions. STEVE: Yeah. If I couldn't find a solution quickly, I would just go on there and just shamelessly ask questions which they were, in some sense, naive questions. Looking back at them now, it clearly highlighted that I didn't understand the fundamentals, but that's okay because I know I didn't. [laughs] And I'm sharing that with everyone right now, so it's not like it's a secret. Because that was the only way I was going to figure it out, like I said. And I didn't have anyone at that agency to ask for help. So that got me into the mindset of just ask for help. But it also got me into a mindset of...one thing was, okay, I can't just paste the entire error message, like, the entire 3,000-line error message from the logs onto Stack Overflow. That's not going to help anybody. No one's going to answer that question. I needed to start to get good at distilling down the problem into its smallest part to then be able to share it, so I would at least incentivize someone to answer it versus pushing them away because who wants to read a non-formatted log file dump? JOËL: That is a skill in and of itself. STEVE: Yeah. I mean, it took time, don't get me wrong. And at first, I was posting those [laughs] giant log files. I would just say, "Hey, can you help me?" [laughs] And it's like, there's no context, and it's just 3,000 lines of gibberish. So obviously, I quickly learned, well, I got to make these bite-size. But then, from there, I slowly learned over time thanks to the community, and just the advent of the internet, and searching and everything like that. But then I got to a point where I was confident enough with the skills I was learning that I wanted to start giving back and if nothing else, it was really just to help future Steve. So when I would run into an issue that I couldn't solve, typically at this point, it was like WordPress or Drupal issues. Once I was able to solve it, I would then write up a blog post with that solution, and they were very simple posts. And just by chance, they happened to be very search-engine friendly because I would just, like, the title of the post would be basically the error message or how to do X in Drupal. Obviously, as a software developer, no shortage of problems, right? Like, every day, you're going to run into something that you actually just do not know the answer to. So I would just amass dozens of these problems. And if I found one interesting enough, I would post about it. And I just got into a habit of that because, like I said, if nothing else, it helps me for the future. But then it's also nice to know there's certainly going to be someone else out there who has the same issue. And it's kind of exciting to think someone on the other side of the globe is going to possibly search this thing and maybe land on my website or something, just like I have done countless times where I've put in something into a search engine, and I land on someone's website, typically the thoughtbot website, [laughs] and I read the solution there. So it's exciting to be part of that. JOËL: Were you ever afraid that somebody else would come along and tell you your solution is wrong? STEVE: I wasn't necessarily afraid because that comes with the territory. Honestly, fortunately, I've never really had a situation where someone was outright mean or disrespectful. For the most part, I find folks are very helpful. But it does help like I said, if you distill those questions down and make it simple for someone to help you with. But yeah, I mean, that is one of the...I don't want to say risks, but that comes with the territory of learning in public, which is you might face criticism. MID-ROLL AD: Debugging errors can be a developer’s worst nightmare...but it doesn’t have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake’s debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake’s lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! JOËL: One thing that I really appreciate with some of the things that you share on social media is kind of like what we say here on the show, sharing a little bit of what we've learned along the way. So you get to follow Steve's journey. And it's like, I'm trying this problem; here is the solution I have so far. It seems to solve some problems, not everything. Tune in tomorrow to hear how the problem keeps developing. STEVE: Yeah, exactly. That's kind of why I try to make sure I'm giving back at least half as much as I'm taking, so to speak. So in these transactions, like on social media, I'm stumped on something or maybe not even stumped, but I'm just, like you said, exploring an idea. And I want to have it peer-reviewed, so to speak. I mean, in some ways, some of these things are almost like a Twitter code review, right? It's just like, instead of having the formality of doing it on GitHub or whatever, it's just like, here's a snippet, quick gut check here. And then what's nice is that people are nice enough to respond with what they think. They'll reference other posts or other projects that might touch upon that. And what's nice and what I hope is happening with these exchanges is maybe someone learned a little something about what I just posted. Because I know that I'm certainly learning something from the feedback I get. And then again, it's almost like code review. You get this nice history of what this idea is about and then different stances on it. And then it just sort of serves as a little bit of a learning tool right there. And then yeah, I'll try to follow up later on, like, hey, here's where I landed now. But maybe it's a little more fleshed out. JOËL: What are maybe some drawbacks of this concept of learning in public? Are there some reasons you might not want to or not be able to do this? STEVE: I do think there are...maybe not drawbacks, maybe just risks. An obvious one I can think of is if you're working on proprietary software; for example, you legally probably can't share anything that you're working on. So that makes it challenging because you can't just straight up take a screenshot of your editor [chuckles] and be like, "Hey, look at this cool thing I'm working on today." That adds a little bit of a roadblock because then you probably have to simplify it or, I don't know, anonymize it in a way that it's just generic. So it just adds a little bit of extra work. But in some ways, that might actually be a good thing because then you've simplified the problem to its purest form, so to speak. Another drawback we kind of touched upon is you're opening yourself up to criticism, that can be a challenge. Everyone communicates differently. People may not want to use Twitter, for example, to learn in public. They might just want to have a personal blog and do it that way. JOËL: Turn off the comments. STEVE: Exactly. Turn off the comments. If you're someone that is hesitant of criticism or just being on social media in general and all that, learning in public can be whatever you want it to be. So what I mean by that is we talked about Twitter and social media. That's kind of an obvious way to learn in public. But another way is you could just have some GitHub repos or your own personal blog, you know, things like that. What's being implied here is learning in public means, like, public, anyone could access it. But I want to challenge that because public could mean different things in different contexts. So at thoughtbot, for example, we have our dev channel, and people post there all the time. And that's public in a sense, but it's not public to the world. So it's a little more controlled. You know that you're going to get helpful feedback. It's a safe space to do that. So I would encourage folks listening now that work in an agency or just work in software development in general see if you can create your own dev channel at work or something like that if you don't already have something like that because that's a good way to, I guess, encourage people to learn in public. JOËL: I love that you're redefining public a little bit here and the idea that public could just mean your team at work or your company. That's a concept that I really like because now maybe it's a little bit less intense to share with them. And it can be something as simple as today I learned. It could be a question about a particular technical thing, or here's the thing I did; it works. Is there a better way to do it? STEVE: Exactly. If you think about it, code review is a form of learning in public that's built into our day-to-day job because it encompasses a lot of these things. You have to be...I don't want to say ready to take criticism, but it's very common to open up a PR, and you're going to get feedback on it. The reason I'm hesitant to say criticism is there's a connotation of just criticize me and the person is being rude or something; I don't mean that. I just mean someone who is being critical of your work in the sense that they're making sure it meets the requirement. And it is quote, unquote "good code" given the constraints. So you have to open yourself up to criticism that way. You're also creating these little artifacts because, in code review, there's going to be a back and forth. Someone might suggest a change; someone else might praise or just give you a shout-out to be like, "Hey, I've never seen this before. I've never seen this method before or this pattern before. This is really neat. It reminds me of something I learned over here." And they might paste a link to something else. So yeah, code review is a form of learning in public. It's like a very controlled, simplified version of that. And it can also be a good source for learning in public through social media. Because then from that, you get this distilled concept that you can then share to the world or just at work with other people that may not be on your team. JOËL: thoughtbot has a few, I think, different cultural things that we like to do that all converge on some of these ideas, one being that we have dedicated investment time to try to improve ourselves. Two being that we try to share anything that we create as publicly as possible. So default to making something publicly available unless there's a good reason to keep it private which is the opposite of a lot of companies. And then finally, bringing that all together, trying to, in the things that we learn, in the work that we do, pull out shareable artifacts. So if you're reading a book, if you're working on a project, is there something tangible you can pull out of it to share back with the team or even the broader world? And that might just be dropping, "Today I learned this," in our dev channel. It might be putting up a little proof of concept repo and publishing it publicly. It might be, as you mentioned earlier, writing a blog post about a cool technique that you found helpful on a project. So we're constantly trying to find ways to take anything that we've learned and not just make it a personal thing but also try to sort of multiply that to, at the very least, our team but where it makes sense also the broader dev community. STEVE: Yeah, exactly. I don't know about you, but I feel like there are a lot of similarities with learning in public in their many forms with open-source software. Because open-source software is basically learning in public, right? For folks listening who might be hesitant to start getting in the habit of this, I would just encourage you to look at any popular repository and look at all the open issues. And what I mean by that is these popular repositories that are used by millions of people they're not perfect. Like, they didn't get it right on their first try. And you can read the source code and you can see everything about it. And it kind of embodies learning in public in that way. So it opens itself up for criticism but also praise. And then it's also just a resource there where you can learn from it. There are so many times where I'll open up the Rails, like, I'll just go to the Rails source code, not because I need to but because I'm curious, like, how do they do that particular thing? Like, the other day, we were working on something where we had an object or a class, and we wanted it to have two class methods, one called perform, and one called perform with an exclamation point. The details of that don't matter, but I was just kind of like, well, that reminds me of Rails with destroy and destroy with an exclamation point. And I just want to see how do they do that under the hood? Like, not every single detail, but just how does the destroy method with the exclamation point, like, does the call destroy under the hood? What does it do? And I was just like, well, let's just see what Rails does. And we can kind of copy that pattern for what we're doing over here, which was great. And, again, that wouldn't have happened if we didn't have open-source software, which, again, I think is a form of collective learning in public. It's like, it's the source. It's a result of many people working on it. JOËL: Even for projects that have only a single author, I think there can be a lot of value there. Long-time listeners of the show will know that I'm a big fan of the Elm programming language. And I've participated in a few Game Jam events where you have a deadline, typically a few days or maybe a month, to create a game based on a theme. And I've built some games using Elm. Later on, people will ask me about particular patterns that can be used in Elm, maybe related to games, maybe not related to games. And I've been able to link them to parts of that open-source code for the games that I built, which are built under pressure. They're not always great quality. But I can link to a particular section of the code and say, "Here's the pattern we were talking about." And that can spin off a whole conversation. STEVE: Yeah, that's just one of the many advantages to doing these things. And I should also say, too, you say that I'm good at learning in public, but the same goes for you too. I mean, you're constantly sharing things in the dev channel, writing posts. I want to recognize that too because I think that's a skill that you've also mastered. So I appreciate that. JOËL: Thank you. STEVE: You share as much as you do, especially because you have significantly more experience than me. So again, to circle back to the mystery guests, I would hear you talking about mystery guests. I've heard other experienced devs talk about it. But a year or two ago, I'm like, I trust these people. Like, I really trust them. They're smart. They're credible. They have more experience. But I just don't really get what the problem is because I haven't actually experienced it firsthand, but I at least knew to be aware of it. And it was in my back pocket, and I could take it out when I was ready to do a deep dive on that. So if it weren't for things like this podcast or blog posts or other things like that, I feel like the dev community wouldn't be nearly as...it just wouldn't be at the level that it is now. And I don't mean necessarily even Rails; I just mean software development in general. Imagine if all programmers just worked in isolation and couldn't use information from other developers or imagine that in any career, right? Physicians...imagine if they couldn't do knowledge share. So I just think being in the software industry, it's just easier to share what you're doing because we make the internet in a way. So it's like, we're already on the internet all day, so we might as well just sprinkle in what we're learning. JOËL: I have a personal note in my notes. It says that the best knowledge is created in the connections between people. So if you're imagining a graph where people are nodes, and the connections between them are edges, all the best ideas are on those edges where interactions happen between people and not just solo geniuses. STEVE: Exactly, exactly. I like that. JOËL: Power of collaboration. STEVE: Right. It's like a neural network or something. It's just like, everything coming together, passing knowledge along. JOËL: So, Steve, we've talked about how learning in public can be really good for your own personal growth and learning. Are there any other advantages to this approach to work where you're learning in public? STEVE: Yes, absolutely. I think learning in public is very beneficial for junior devs in particular. And there are a few reasons I think that one of which is I think it helps you stand out amongst other candidates that are applying for a job. I think that just because...if you're constantly sharing what you learn and what you know, and again, these can be very small things. I'm not talking about multi-part blog posts or something. I'm just talking about sharing simple code snippets but just being kind of consistent about it. Doing that really helps hiring managers to get a sense for how you think, and how you communicate, and how you code because those are all very important aspects of software development. Like, it's not just coding. If it was just coding, I don't know, GitHub Copilot, that would be it, right? We could all just [laughs] pack up our bags and head home. But there's so much more. There's so much more communicating that is involved in the job. And if you're constantly sharing what you learn, that just makes it easier for maybe a hiring manager or someone to get a sense of how you think, how you code, how you problem solve, and again, how you communicate too because maybe you'll face some criticism like in the comment section or something. I'm not saying that's justified, but also, maybe that's an opportunity to practice your communication skills and maybe ask that person, like, hey, how would you solve this problem? Or, what do you recommend? Because again, to go back to code review, that back and forth, that exchange that happens every single day. And I just think that if you're learning in public, it's just going to make it that much more easy for someone to get a sense of what you're like before they've even met you. JOËL: And I think it's a really virtuous cycle here because you mentioned how this is a great way to show your work for potential employers, but at the same time, it's a great way to practice that work. You're talking about how this will help you improve your communication. But at the same time, it's also proving to everyone that you are good at communicating or that you have grown a lot in your communication. STEVE: Exactly. Yep, exactly. If you're consistent about it, too, you could just scroll through your old blog posts and see what was I talking about three years ago? Versus what am I talking about now? And hopefully, there'll be some improvement and more depth to the articles. And again, it's just a great way to let folks know how you think and how you solve problems. JOËL: I found that it's not just valuable for junior developers. I think it can be really helpful throughout your career to have public artifacts to point to. I've found that for some of my clients, being able to point back to blog posts I've written, or even conference talks I've given helps build trust, helps to build credibility for some of the work that I'm trying to do. STEVE: Exactly, yep. And what's really exciting about it is in that moment, when you send that link or send an artifact, that transaction took two seconds. But it just embodies so much of that credibility because it took you years to get all that knowledge. But now, it's just foundational. You have this big foundation of artifacts that you can share. I think that's just wonderful. JOËL: Keep learning in public. You're building an archive of valuable resources that will just keep compounding in value over the course of your career. STEVE: Exactly. That's a good way to put it. I like that. JOËL: Well, Steve, thanks so much for joining us on the show to talk about learning in public. If people are curious to see some examples of how you do this, where can they find you online? STEVE: If you just search Steve Polito Design, you'll find me, which is kind of a callback to when I was studying graphic design back in college. So that's the best way to find me. JOËL: So this is a handle on multiple different social media sites? STEVE: Yep, exactly. JOËL: Excellent. We'll make sure to link a few of those in the show notes as well. Thank you so much, Steve, for joining us this week to talk about learning in public. Do you have any last words you'd like to share with our audience? STEVE: Yeah, I just want to thank you, again, for having me on the show. Just for context, a lot of what I learned about software development came from The Bike Shed, so, again, plus-one for learning in public. It helps other people. So it's very exciting to actually be on the other side of the show right now as a guest. So thank you very much. And congrats again on the new hosting gig; so you'll be learning in public too now, so this is great. [laughs] JOËL: The show notes for this episode can be found at bikeshed.fm. This show is produced and edited by Mandy Moore. If you enjoyed listening, one really easy way to support the show is to leave a quick rating or even a review in iTunes. It really helps other folks find the show. If you have any feedback, you can reach us at @_bikeshed or reach me @joelquen on Twitter or at hosts@bikeshed.fm via email. Thank you so much for listening to The Bike Shed, and we'll see you next week. Byeeeee!!! 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:Airbrake: Deploy fearlessly and fix bugs faster with Airbrake Error & Performance Monitoring. Airbrake notifiers are available for all major programming languages and frameworks, and install in minutes, with an open-source SDK-based install and near-zero technical debt. Spend less time tracking down bugs and more time developing. Visit Frictionless error monitoring and performance insight for your app stack.Support The Bike Shed
undefined
Aug 16, 2022 • 52min

350: 21 Bell Salute

It's Steph and Chris' last show. Steph found a game, and if you've been following the journey, all of the Test::Unit test files are now live in RSpec. JWTs really grind Chris' gears. They wrap up with things they've learned, takeaways they've had, and their proudest podcasting moments. They also thank all the folks who've helped make The Bike Shed happen. This episode is brought to you by Airbrake. Visit Frictionless error monitoring and performance insight for your app stack. Microservices Transcript: CHRIS: One more round of golden roads, our golden. So here we go. STEPH: Oh, one more round of golden roads. Okay, maybe that's going to get to me today. [laughs] CHRIS: [singing] Golden roads take me home to the place. STEPH: [singing] I belong. CHRIS: Yeah, there you go. Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Chris Toomey. STEPH: And I'm Steph Viccari. CHRIS: And together we're here to share a bit of what we've learned along the way, at least one more time. So with that [chuckles] as an intro, Steph, what would you say is new in your world? STEPH: Hey, Chris. Well, today is the big day. It is the day that you and I are recording our final Bike Shed episode, which we have all the feels about, and we will definitely dive into. But to ignore some of that for now, I have another small fun update I can provide about a new game that I found. So one of the things that's new in my world is I started playing a new board game with Tim; it's called Ticket to Ride. Have you heard of that? CHRIS: I have. I don't know if I've played it. I feel like it's a particularly popular one now. But I don't know if I've ever had the pleasure. STEPH: It's a very cute game, so we have the smaller version of it. For anyone that's not familiar, it's essentially a map. And then there's a bunch of spots where you can build trains and connect them, and then you get tickets. So your goal is that you're going to connect one location to another location. And then you get points and yada yada, but it's so much fun and especially the two-player version. It's like this perfect 20, maybe 30-minute game. I'll be honest; I'm not really a board game person. I always enjoy it. Once I get into it, then I'm like, this is great. I don't know why I was resistant to this. But every time someone's like, "Do you want to play a board game?" I'm like, "Not really." [laughs] I first have to get into it. But I have really enjoyed Ticket to Ride. That's been a really fun game to play. And it's been a nice way to, like, even during the day, we'll break for lunch and squeeze in a game. CHRIS: Well, I love good two-player games. They're hard to find. But when you find a good one, and it's got that easy pickup and play...I believe I'm going to now purchase this. And thank you for the tip. STEPH: Yeah, this is definitely one of those where it's easy to pick up, and then you can get the expanded board. So there's a two-player version, but then yeah, you can get one that's a map of the U.S. or a map of Europe. And I think it accommodates up to five players as the maximum, so not a huge group but definitely more than two. On a slightly more technical note, I have something that I'm very excited to share. It is a journey that you have been on with me, that everybody listening has been on this journey with me. And I'm very excited. I see you nodding your head, so I'm guessing that you're going to know where I'm headed with this. But I'm very excited to announce that all of the Test::Unit test files now live in RSpec. So that is a big win. I'm very, very excited for that to be a previous state of life and not an ongoing state of life. Because I have certainly developed too much niche knowledge around migrating these tests, and that became apparent to me when I was pairing with another developer that works with the client because they had offered...they had some time. They're like, "Hey, do you want help migrating a test file?" And I was like, "Sure." I was like, "But this is wonky enough, like, we should pair and work on this together because I just know some ins and outs. And I don't want you to have to learn a lot of the hard lessons that I've learned." And the test that we happened to pick up was very gnarly. It had a lot of mystery guests. And we spent, I think it was a good two hours. And we only migrated one of the tests, so not even a full file but one of the tests. And at the end of it, I was like, I know way too much about some of the oddities and quirkiness of this. And we got through it, but we decided that wasn't a good use of their time for them to go at this alone. So that's why I'm extra excited and relieved because I didn't want this task to carry on to someone else. So, hooray, we did it. CHRIS: Hooray. Just in time. You're Indiana Jones grabbing your hat right as you roll out and off to [laughs] be away from the project for a bit. So you stuck the landing. Well done, Steph. STEPH: Thank you. Thank you. So that's some great news. And then also, everything else in life is pretty much focused around getting ready for maternity leave. That's about to happen soon, and I am so ready. I have thoroughly enjoyed a lot of the things that I'm doing, [laughs] but goodness, being pregnant is hard. And I am very much ready for that leave. So also, a lot of the things that I'm doing right now are very focused on making sure everything's transitioned and communicated and that I just feel really good about that day of departure. That covers all the newness in my world other than the big thing that we're just not talking about yet. How about you? What's new in your world? CHRIS: Well, continuing to skirt the bigger topic that we will certainly get to in the episode, what is new in my world? I'm actually quite excited workwise right now. We have a much larger body of work that finally we got the clarity. All the pieces fell into place, and now we're sort of everybody rowing in the same direction. There's interesting, I think, really impactful code that we're writing for Sagewell right now. So that's really fantastic. We've got the whole team back together on the engineering side. And so we're, I think, in the strongest and most interesting point that I have experienced thus far. So that's all really fantastic. On a slight technical deep dive, you know what really grinds my gears? It's JWTs. JSON Web Tokens and I have never gotten along. It's never been a match made in heaven. And we have a webhook that comes from Plaid. Plaid is a vendor for connecting bank accounts and whatnot. And they have webhooks like many people do. So they can inform us when things change, lovely feature of how we build web apps these days. But often, there's a signature that says, "This is definitively from us, and you can trust us." And usually, it's some calculated signature, HMAC, or something like that. For some reason, Plaid's uses JWTs, and more than that, they use JWKs. So there's JWT which is the signature. That JWT itself is signed with a JWK. You have to fetch the JWK from their server based on the key ID in the header of the JWT. But how do you know if you can trust the JWT before you've gotten the JWK? All of this broke in a recent upgrade. We went from Heroku-20 to Heroku-22 to the new platform with Heroku, which bumped us to OpenSSL 3.0, and it turns out JWT doesn't work with it. And so that's sad. It's a no. It's going to be a no. It turns out the way that OpenSSL 3.0 works is incompatible with some of the code paths in JWT. And so I was like, wait, we just can't do this? And it's low-level cryptographic primitive stuff that I'm not comfortable messing around with. I'm not going to hop in there and roll up my sleeves. And even just getting to the point that I understood what was broken about this took like an hour and a half just to sort of like, wait, which is okay...so the JWT signs and encodes. And this will be a theme that we come back to later, but I think web development should be simpler. I think we should strive for simplicity. And this is a perfect example where I'm guessing Plaid uses JWTs and that approach to communicating security things often, but I've not seen it used much for signing webhooks. And, oof, it led to a complicated day. And it's unfixable now as far as I can tell. There is a commit on the JWT Ruby repo as of five days ago, but it doesn't build in our system. And it's not released. And it's just a mess. So yeah, engineering is complicated. I'm both wildly excited about what we're doing at Sagewell, and then today was this local minimum of like, oh, JWTs again. Again, we find ourselves battling. And you won today, but hopefully not for too long. STEPH: Oof, how did this manifest that you first noticed? So is it because a webhook suddenly stopped working, and that was like the error that rose up, and that's what helped you dive into it? CHRIS: Yeah, we have a little bit of code in the controller for where Plaid events come in. We calculate and verify the signature of the webhook to make sure that it's valid, and we reject it otherwise. And we alert ourselves via Sentry, and then we also have a Datadog scan that can show what's the status code of the response. Because these are incoming HTTP payloads or requests, and so we can see there were 200 up until this magical day when suddenly everything changed. And that was when we switched Heroku stacks. And then we can see it also in Sentry. So we're able to look at it, and we're like, why are none of the Plaid webhooks able to verify the signature anymore? That seems weird. And so then Datadog confirmed that it consistently was broken from this point in time. And then we were able to track that back. It was also pretty easy to guess because the error was "pkeys are immutable in OpenSSL 3.0," and that was the data. And I was like, oh, cool, that sounds fun. Let me go figure out what that means. STEPH: [laughs] Well, it's a nice use of Datadog. I remember in the past you were talking about adding it. And I was excited because I've never been at that point where a team has just introduced it; either a team doesn't have it, and they wish they had more insights, or they have it and don't use it. And nobody ever checks the board. So that's a nice anecdote for Datadog helping you out. Yeah, I'm not envious of your situation, friend. CHRIS: I do love the cup half full take [laughs] that you have on the overall situation, but that's nice how Datadog worked out for you. And you know what? It was. Thank you, Steph, for once again being that voice of positivity. STEPH: I appreciate that you enjoy it because there are times that when someone points it out to me that I do that, I have to be like, "I'm sorry, I'm not trying to be toxic positivity over here. [chuckles] That's just how my brain works." CHRIS: Oh, you are definitively not toxic positivity. That's a different thing. Because you ended with but also, I feel bad for you, and I'm glad that I'm not in your shoes. So you are the right level of positivity. I don't think I could have talked to you for three and a half years as co-host on a podcast if I didn't appreciate the level of positivity or the general approach that you bring to thinking about stuff. STEPH: Okay. Well, to borrow a phrase from Matt Sumner, who has been a guest on the show, cool, cool, cool, cool. I'm glad my positivity has been well calibrated. And I was about to say I'm interested to hear how this turns out for the team. [laughs] But we're in an awkward spot where I mean, you and I, we can still totally chat. But listeners won't get to hear the rest of that particular saga. I mean, you can share. I mean, you do you. I'm setting all sorts of boundaries for you right now. Okay. And now I'm just rambling, and I'm getting weird with it. Because the truth is that, you know, we won't be back. And this is our final episode together. So I think let's just go ahead and rip off the Band-Aid. Let's dive into it. Let's talk about it. Given that it's our last episode that we are recording, we thought of a couple of things that we'd like to talk about. You brought up a great idea that I'm excited to dive into. Do you want to lead us in? CHRIS: Sure. Well, if we go back all the way to Episode 172, that is the first episode that you came on as a guest. I actually continue to really love the title of that episode, which is What I Believe About Software. And it both captured that conversation really well, but also, more generally, it's actually become the tagline of the show when we do our little introduction. What do we believe about building great software? Et cetera. And I think that's been the throughline of the conversations that we've had is what remains true. What are the themes? Not necessarily the specific technologies, although we certainly talk about that. But what do we believe about building great software? And so today, I thought it would be fun for us to talk about what do we still believe about building great software? It's roughly three and a half years or so that we've been doing this. What's still true? STEPH: Oh, well, I have the first unequivocal one, the thing that I still believe about building great software, and that's you should hire thoughtbot. That's definitely the way to go. We'll help you get it done, not that I'm biased in any way. CHRIS: No. I'd say collectively between us; there's zero bias with regard to thoughtbot or any other web development shop out there. But thoughtbot is the best. STEPH: All right, perfect. So we've got the first one, the clutch one of hire thoughtbot. And then I also really like this topic. And I still think back to that first episode that I recorded with you and how much fun that was and how that really got me to start thinking about this. Because it was something that, at the time, I didn't really reflect on a lot in terms of what does it take to build great software? I was often just doing the day-to-day actions but then not really going high-level think about it. So I'm excited this is one of the topics that we're revisiting. So for the next one, this one is, I don't know, maybe it's a little cutesy, but I was trying to think of an alliteration that I enjoyed. And so this one is be an assumption assassin. So what assumptions are you making? And then how can you validate or disprove them? And that is something that I find myself doing constantly. And it always yields better work, better questions, better software, better code, better code reviews. And that's my first one is be an assumption assassin and identify what assumptions you have. And I had a really good example come up today while I was having a conversation with Joël about something that I was looking to merge. But I was a little hesitant about it because there are some oddities that I won't dig in too deeply. But essentially, there's a test that I migrated that highlights an existing concern in the code. And I was like, should I go ahead and merge this test that documents it, or should I wait to fix that concern and address it? And he brought up a good point. And he's like, "Well, we're assuming it's a bug and an issue, but it may not actually be depending on how the software is being used." And so then he was encouraging me to reevaluate that assumption that I had where I'm like, oh, this is definitely a problem to, like, I don't know, is it a problem? Let's ask somebody. CHRIS: First off, I love that as a theme, as one of the things that you still believe about software. Second, I believe you correctly said that you were looking for an alliteration, but my brain heard acronym. STEPH: [laughs] CHRIS: And so then I was like, B-A-A-A. Is it BAAA? What are you going for there? Oh, you just wanted a bunch of As. Okay, I got it now. Secondly or thirdly, I think I'm on my third now. Apparently, within Sagewell team culture, one of the things that I'm most known for is... there are two phrases: one is just to name it, and the other is to be clear. And these are the two things that I do apparently constantly so much that it's become a meme within the team. It's just like, okay, everybody's been talking. But I just want to make sure we're on the same page here. So just to be clear, or just to name it, here's what I'm seeing. But I agree; I think taking those things...what are the implicit bits? What are the assumptions? And making them more explicit. Our job as developers is just to yell at computers all the time and make them try and do human stuff. And there's so much room for lossy conversions at every point in that conversation chain. And so yeah, being very clear, getting rid of assumptions, love it. It's all great stuff. Actually, in a very related note, the first on my list is that code is for humans to read. This is one of the things that I believe most deeply and most impacts the way that I write software. Any given piece of functionality that we want to author in our code feels like 10, 20, 50, frankly, almost infinite different versions of the code that would produce nearly identical functionality. So at the end of the day, the actual symbols and strings of text that we bring together to write the code is all about other humans, other people on your team, you five months from now, you a week from now, frankly, or me. I'm going to say me, me a week from now. I want to do future me and everyone else on the team a solid and spend that extra 10% of okay, I have something that works now, but let me try and push it around and try and massage it into a shape that is a little more representative of how we're actually thinking about the code, how we talk about it as an organization. Is that the word that we use to describe that domain concept? Maybe we could change that just a little bit. Can I push more of this into the private API? What actually needs to be known here? And I think that's where I'm happiest is in those moments because that's where all of the parts of the job come together, the bit where I trick a computer into doing what I want and simultaneously making it so that that code is revisitable, clear, expressive, all of those things. So yeah, code is for humans. And that's true across every language, and framework, and domain that I have worked in. And I've only believed it more and more so over time. So yeah, that's mine. STEPH: Yeah, I love that one. That's one of the things that comes to mind when people talk about disliking code reviews. And I can imagine there are a number of reasons that people may have had a poor experience with a code review process. But at the end of the day, if you're not getting that feedback or validation from fellow humans, then how do you know that you've been successful, that you've written something that other people can follow up on? Which goes back to the assumptions in terms of like, you're assuming that you have written something that your future self or that other people are going to be able to read and maintain down the road. So yeah, I love that one. One of the other things that I still hold really true to building great software is prioritize early and often. So always be checking in to understand with your users, with your tech concerns, with data that you may have, new insights, and then just confirm that yes, you and the team are constantly working on the thing that has been prioritized and that is the most important. And also, be ready to let go. That can be really hard. I have definitely had those moments in my career where I've spent two weeks working really hard on something. And then we've realized that the thing that we were pursuing isn't that valuable, or it's something that users don't need or actually want. And so it was better to let go of it than to pursue it and ship it anyways. So that's one of my other mantras that I have adopted now is prioritize, prioritize, prioritize. CHRIS: Unsurprisingly, I agree wholeheartedly with all of that. We're still searching for that thing, that core thing that we disagree on other than Pop-Tarts and IPAs. But I don't know that today is the episode that we're actually going to find that. But yeah, prioritizing is such a critical activity. And it is this interesting collaboration point. It gets different groups together. It's this trade-off. It's this balance. And it's a way to focus on and make explicit the choices that we're making. And we're always making choices. We're always making trade-offs. And so being more explicit, being more connected and collaborative around those I believe in so, so, so much. So love that that was something on your list. Let's see, next up on my list is reduce complexity, just sort of as an adage, just always be reducing complexity. It is amazing to me in my time, particularly as a consultant, but even now, this is something that I hold very true is just it's so easy to grow a system in anticipation of future complexity or imagine that the performance concerns that we're going to run into will be so large that we must switch from Postgres and a nice, simple atomic database into a sharded, clustered Kafka queue adventure. And there are absolutely cases that make sense for that sort of thing. But at a minimum, I beg of you, anyone starting a new system, don't start with microservices. Don't start with an event queue-based system. These are wildly complex versions of what often can be done with so much simpler of an application. And this scales through to everything. What's the complexity of an API? Do we need caching in that API layer? Or can we just be a little bit inefficient for a little while and avoid the complexity and the overhead of caching? Turns out caching is a tricky thing to get right, just as an aside. And so the idea of like, oh, let's just sprinkle in a little bit of caching. It'll be easy, and then we'll get better performance, like, yeah, but did you get it right? Or did you introduce a subtle bug into your program that's going to be really hard to debug later? Because do you cache in development? Well, maybe, I'm not sure, could be. So over time, this is something that I've sort of always felt, but I've only ratcheted it up. It's only something that I've come to believe in more and to hold more firmly to. I think earlier in my career, it was something that I felt, but I would more easily be swayed by aspirational ideas of the staggering amounts of traffic that we would be getting soon or the nine different ways that the data model will expand. And so, we should code the current version in anticipation of that. And I have become somewhat the old man on his lawn yelling at the clouds like, "Nah, we don't need it yet. We can grow to that." And there's a certain category of things that are useful to try and get out in front of and don't introduce additional complexity, but they're a tiny, tiny list. And so, for most things, my stance is what's the simplest thing that we can get away with right now, that still provides a meaningful experience to our users, that doesn't compromise on security or robustness or correctness but just solves the problem we have right now? And over and over and over again, that has served me incredibly well. So yeah, keep that complexity at bay. STEPH: That is one that I've definitely struggled with. And frankly, it works in my favor, that idea of keeping things simple. Because I'm terrible when it comes to predicting the future or trying to build things in a way that I just don't have enough information to really drive the architecture or the application that I'm building. So anytime I'm trying to then stretch and reach for the future in those ways unless I really have a concrete understanding of I am building for these particular scenarios, it's really hard to do. So I very much like keeping it simple and not optimizing before you need to. And it reminds me of I think it's Mark Twain, who has a quote, "Worrying is like paying a debt that you don't owe." And that's something that comes to mind for me when also writing code and building features and software is that I tend to be someone who will worry about stuff. And I'm like, oh, is this going to be easy to extend? Is it going to be what it needs to be six months from now if we need to add more features to this and build on top of it? And I have to remind myself it's like, well, let's just wait. Let's wait till we get there and we know more. One of my other ideas that couples nicely with the one that you just shared in regards to keeping things simple and then waiting for those needs to arise is that mistakes are going to happen. They are a part of the process. As we are learning and growing and we're stretching our skills and trying things out, things are going to go wrong. We're going to introduce bugs. And to take those opportunities, that's when we start to use that feedback to then improve things like observability, like capturing logs, and how we handle error reporting or having a plan for emergencies. So maybe that's the part of worrying that can pay off is thinking through, all right, if something does break, or if something gets shipped that shouldn't, then what is our plan in how we handle that? How do we roll back? Or how do we get things back to a stable build? CHRIS: It's funny. I was actually visiting with a friend this past weekend, and we were chatting more generally about life things but the idea of worrying and anticipation and trying to prepare for every bad outcome. And there's the adage of an ounce of prevention is worth a pound of cure. But increasingly, both in life, depending on the context, and in code, I've found that I've shifted to the opposite of it's impossible to stop everything. There are going to be bugs that are going to get out there. There are going to be places where we code things incorrectly. And I would rather...I still want to try as hard as I can to get things right, to be clear. I'm not giving up on trying. But I'm all the more focused on how do we know and how do we recover when those things happen? So it's interesting that you just described exactly that, which, again, is a very human life conversation, and yet it applies to the code. STEPH: I love that rephrasing of it. Instead of the mistakes are going to happen, it's, like, how do we know, and how do we recover? I think that's perfect. I've also found that by answering the how do we know and how do we recover, that really helps you build trust with clients as well. Because again, things are going to happen, things are going to break. And the more prepared you are for that and then the better plan that you have, and then they can watch how you execute that plan, and it’s going to establish a lot of deep trust with other engineers and also the team that you're working with, that you have been thoughtful and that you have ideas on how are we going to address this? Instead of waiting for that moment to happen. That's going to happen too. You're going to make decisions in the heat of the moment. But I have found that to be a really useful way to establish yourself with a team in terms of I care about this team and these processes and this application. So how do we handle the bad times, not just the good times? I do want to circle back because you alluded to the fact that you and I, we've tried to find things that we disagree on. And so far, Pop-Tarts and beer have been the two things that we disagree on. But I do have a question for you that maybe I will disagree with you on. But I need to know some more about it first. You have alluded to there's the Brussels snack, (Oh, I'm going to get this wrong.) Brussels sprout snack hour or working lunch, something combination of those words. [laughs] And it's the working lunch that has stuck out to me, and I've wanted to ask you about it. So here I am. I'm asking you about it. What's a working lunch? What's the Brussels snack happy hour, snackariffic working lunch look like? CHRIS: This is fantastic. I love that you waited until the last episode that this was rolling around in the back of your head. And you're like, are you making the team work through lunch? And now, on this final episode, we get to address the controversy that has been brewing in the back of your head. Spoiler alert, no, this is just ridiculous nomenclature. These are two meetings that we have that are more like, let's get the dev team together and talk about stuff that's in our platform sort of developer experience. Or stuff in observability often is talked about in this context because it doesn't quite impact users, but it's how we think about the work. And so there are two different meetings that alternate every other week. So every Friday afternoon, we do this, but it's one of two meetings depending on the day. So there's a crispy Brussels snack hour that was the first one that was named, which was named purely for nonsense reasons because we don't have anything else that's named nonsensically in our organization. And so I was like, oh when we name this meeting, we should make it nonsense because we don't have any other...We don't have, you know, an SOA microservices fleet with Barbie doll and Galactus and all of the other wonderful names. Those are references to the greatest video ever about microservices; if you've not seen it, that will be in the show notes. It's required reading. But anyway, we don't have that. And so we thought, let's be funny with the name of this. So the crispy Brussels snack hour is one, and the crispy Brussels we wanted something that was...the first one is a planning meeting. The second is like, let's actually sort of ensemble program. Let's get the four of us together, and we'll work on some of the stuff that we're talking about here but as a group. And so I wanted the idea of we're working, and so I was like, oh, this will be the crispy Brussels work lunch. But it's purely a name. It's the same time slot. It's 3:00 o'clock on a Friday afternoon. [laughs] So it is not at all us working through lunch. I don't think we should work through lunch. I'm concerned that you thought that for a while, and you were just like, I'm a little worried, but I'm not going to bring it up. But I'm glad we got to cover this before we wrapped up this whole Bike Shed co-hosting adventure together. STEPH: I feel relieved and also a little robbed of an opportunity for us to have something that we disagree on because I thought this might be a thing. [laughs] CHRIS: We can continue searching for that thing. But maybe it's okay that we agreed on most stuff for the run [laughs] of this fun, little show that we did together. STEPH: Yeah, that's gone on quite a time. We've got like three years together that we have managed to really only find two, I mean, very important of course, two things. But yeah, it's been pretty limited to those two areas. And each time that you'd mentioned the work lunch, I was like, huh, I need to ask about that because I have feelings about it. But then, you always would dive into very interesting stories of things that came out of it, and I quickly forgot about it. So this feels good. This feels like very good important closure. I'm glad that this finally surfaced. But circling back, since I took us on a detour for a little bit, what are some other things that you still hold deeply about building great software? CHRIS: I've really got one last thing on the list. It's interesting, there's not a ton technically in this list, which I think represents broadly how I feel about software, and I think how you feel about software. It’s like, it's actually mostly about how the people interact at the end of the day. And you can program in any language or framework, and you can get the job done. We certainly have our preferences and things that we enjoy. But the last one really rounds us out, which is think about the users. I always want to be anchoring the conversations that we're having, the approach that we're taking to building the software in what do the users think? Who are our users? What do we know about them? What do they care about? How are they using this technology? How is it impacting their lives? We've talked a number of times about potentially actually watching the sales demo as an engineering team, trying to understand what's the messaging that we're putting out into the world for this piece of software that we're building? Or write along with customer support and understand what are the pain points that people are hitting? And really, like, real humans, what are they experiencing? Potentially with a name attached. And that just changes the way that you think about the software. There's also even the lower-level version of it. As we're building classes or modules, what are the public facets of that, and what are the private API? What's the stuff that we're hiding away? And what's the shape that we are exposing to the outside world for varying definitions of outside? And how can we just bring in a little bit of empathy to try and think about, again, in the case of like the API for a class, it's probably you on the other side of it, but it's future you in a slightly different mindset with a little bit less information and context on the current problem that you're working on. And so, how can we make things easier for ourselves in the code, for our users at the end of the day? How can we deliver real value that is not mired in the minutiae of technical complexity and whatnot but really is trying to help people live better lives? That's a little too fancy as I say it out loud. But it is kind of the core of what I believe, so I'm not going to take it back. STEPH: I love how you've expanded users where more traditionally, it's people that are then using the software. But then you've expanded it to include developers because that is something that is often on my mind and something that I just agree with wholeheartedly in terms of when you're writing software; as you mentioned before, software is for people. And so we want to include others. And it does improve people's lives. People show up to work every day, and if you've been thoughtful if your past you has been thoughtful, it's either going to give you your future self a better day, or it's going to give other people a better day. So I think that's a very fair statement, improving lives by being thoughtful in regards to focusing on the users, people consuming software, and working in the codebase. CHRIS: I know we've talked about this before, but I was having a conversation with one of the developers on the team at Sagewell just last week, and they were mentioning how they really loved working on admin features. And I was like, oh, that's interesting. Let's talk more about that. And it was really it's that same thing that I think you and I have discussed of like there's that immediacy. There's that connection. These are actually colleagues, but you can build software to make their day better. You can understand in detail what the pain points are. What's the workflow that as you watch it, you're like, oh, I could put a button up in the corner of the screen that would automate almost all of this and your day would be that much faster? Oh, let me do that. That's exciting. And so I love that as another variation of it, like, yeah, there's for other developers. There's also for the admin team or other users in the organization of the software. There are so many different versions of users, but I think I think we build a better thing if we think about them more. STEPH: I have definitely worked with teams where I can tell that certain people are demoralized, and it comes down to they feel frustrated and often disconnected from the people that they are building for. And so then you really feel isolated. I'm pushing code around, but I don't really see the benefit or the purpose of it. And I think that's very hard for developers who typically want to build something that's going to be useful and not feel like it's just going to be thrown away. So connecting your team to those users, I certainly understand. Getting to build something for your colleagues and then they get to say how much they like it is an incredible, rewarding experience. You also touched on something that I really appreciate, where you highlighted that a lot of the technical decisions that we make are important, but they're not at the center of the things that we believe when it comes to building great software. And that's something that I will often reflect on. Like, as we were thinking through these particular ideas that we still hold true today, how mine are more people and process-focused and rarely deep in the technical weeds. And there are times that I think, well, shouldn't there be something that's more technical, something that's very concrete? Yes, you should build your code this way or build your application or use a specific technology. But after all the projects and teams that I've been a part of, that's just usually not the most important part. And so I appreciate that you highlighted that because sometimes I have to remind myself that, yes, those things can be challenging, but it's often with people and process. That's where the heart of great software lies. CHRIS: That's a fantastic phrase, I think, that really encapsulates all of the conversations that we're having here. MID-ROLL AD: Debugging errors can be a developer’s worst nightmare...but it doesn’t have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help you cut your debugging time in half. So why do developers love Airbrake? Well, it has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake’s debugging tool catches all your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake’s lightweight APM enables developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps and includes modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. So head on over to airbrake.io/try/bikeshed to create your FREE developer account today! CHRIS: Actually shifting gears a little bit, so we've just talked about what we still believe about building great software. I'm intrigued. We've been chatting for a number of years here on this microphone, these microphones. We have separate ones because we're in different states. But I'm interested; what have we changed our minds about? What have you changed your mind about, Steph? I got a couple of ideas, but I'm intrigued to hear yours. STEPH: Nothing. I've never been wrong. I've stuck to everything that I've ever thought. CHRIS: That must be boring. STEPH: [laughs] Yeah, that's totally not true there. There are definitely things that I've changed my mind about. One of the things that I've changed my mind about is that people who know the most will ask the fewest questions. That's something that I used to consider the trademark of someone who is a more experienced senior developer in terms of you really know what you're doing. And so you typically don't ask for help or need help very often. And so, I'm going way back in terms of things that I have changed my mind about. But I have definitely changed my mind where people who know the most are actually the ones that do a really great job of constantly asking questions and asking for feedback. And I think that is still a misconception that people still carry forward. The idea that if you're asking a lot of questions or asking for help that you are not as skilled in your work, and I view it as quite the opposite, that you are very good at what you do and that you know precisely the value of your time. And then also reaching out to others for help, and then also just getting validation on things that you may have concerns around. So that's one I've changed my mind on is that I think the more experienced you are, the more questions you tend to ask. CHRIS: Oh, I love that one. It's a behavior that I know...I think we've talked about this before. But as consultants, we try and model it just the like; it's totally fine to ask questions. And because we often come in with less context, it makes sense for us to be asking questions, but I will definitely intentionally lean into it in those contexts to be like, everybody keeps throwing around this acronym. I don't actually know what that is. Let me raise my hand. And my favorite moment is when people disagree on what the acronym or what the particular word or what the particular project is. Like, I ask the question, and people are like, "Oh, it's this," and someone across the room is like, "Wait, that's what it means? I thought it was this totally other thing." I'm like, cool, glad that we sorted that out. Glad that we got that one up in the air. But I actually remember many, many, many years ago, at this point, there was a video series of...PeepCode was the company, and there was the Play by Play series. And so there were particular prominent developers, particularly in the Ruby community. And they would come and sort of be interviewed and pair program. And it was amazing getting to watch these big names that you had heard of, like Yehuda Katz is the one that stands out in my mind. He was one of the authors of merb, which was a framework that was merged with Rails, I want to say around the 3.0 time. And just an absolute, very big name in this world and someone that I looked up to and respected. And watching this video, they had to Google for particular API signatures and Rails methods. They were like, "Oh, how does that work? Is it link to and then you pass the name?" I forget what it was specifically. But it was just this very human normalizing moment of this person who has demonstrably done incredible work in our community and produced very complex software still needs to Google for the order of arguments to a particular method within Rails. I was like, oh, okay, that's good to know. And with complete humility in the moment, I was just like, yeah, this is normal. Like, it's impossible to hold all of that in your head. And seeing that early on shook me off the idea that that's the thing to do is just memorize everything. It's like no, no, get good at asking the questions. Get good at debugging. Get good, yeah, asking questions. It's a core skill rather than a thing that you grow out of. But I definitely shared early on I was like, not allowed to ask questions, that'll be scary. STEPH: I love that example. Because counterintuitively, to me, it demonstrates confidence when someone can say, "Oh, I don't remember how this works," or "Let me go look it up." And so I just very much appreciate when I see someone demonstrating that level of confidence of let's keep going. Let's keep making progress. I'm going to ask for help because that is totally fine, and we are in a safe space. Or I'm going to create a safe space for us to do that. One of my favorite versions of this where you shared like if you ask about an acronym and then people disagree, one of my favorite versions is to ask about a particular area of the codebase and be like, what would you say this code is doing here? What do you think users do here? Like, what is the purpose? What's the point of this? [chuckles] And then having people be able to say, "Oh, yeah, this definitively does this thing." Or people are like, "You know, I'm not sure. I don't even know if that code is getting run." That's one of my favorite outcomes of asking questions. How about you? What's something you've changed your mind about? CHRIS: I made a list of a couple of things like remote is on there. I didn't know if I'd like remote. I wanted to try it for a while. Tried it, turns out I like it a lot. It's complex. You got to manage it, whatever. But that I think everybody's talked about that a bunch. I think probably the most interesting one is deadlines. Initially, in my career, I didn't really feel anything about them. And then I experienced the badness of deadlines. Deadlines are bad. Deadlines are things that come down from on high and then you fail to hit them, and then you're sad. And maybe along the way, you're very stressed and work long hours to try and get there. But they're perhaps arbitrary. And what do they even mean? And also, we have this fixed scope, and they're just bad. And then there was a period of my time where, like, deadlines are bad. The only thing that we do is we show up, and we make the software as quickly as we can. But in reality, there are times that we need that constraint. And in fact, I have found a ton of value in deadlines when used intentionally. So we can draw a line in the sand, and we can say, at this point in time, we will have a version of the software. We have a marketing campaign that we need to align with this. So we got to have something at that point. And critically, if you're going to have a deadline, you've now fixed a point in time. You need to flex other things. And critically, I think the thing to flex is the scope. So we need to have team management. We have user accounts right now, but now we need to organize them into teams. That is like a category of functionality. It's not a singular feature. And so yeah, we can ship teams in the next quarter. What exactly that means is up in the air. And as long as we're able to have conversations essentially on a day-to-day at least weekly cadence as to what will make it in by that deadline and what won't, and we're able to have sometimes the hardest conversations but the very necessary conversations of the trade-offs that we have to make as we're building that software, then I find deadlines are absolutely fantastic tools for focusing and for actually reducing scope but in a really useful way. And getting something out there in the hands of users so that you start to get real feedback so that you start to learn, is this useful? What are the ways that people are using this? What should we lean into and do more of? What maybe should we roll back, actually? So yeah, deadlines. First, I didn't know them, then I feared them. Now I love them but only under the right circumstances. It's a double-edged sword, definitely. STEPH: I, too, have felt the terribleness of deadlines and railed against them pretty hard because I had gone through a negative experience with them but have also shifted my feelings about them where they can be incredibly useful. So I really liked that's one of the things that you've changed your mind about. It also reminds me of one of the other things...I'm going to circle back for a moment to one of the things that I believe about creating great software is to not wait for perfection, and deadlines are a really good tool that helps you not wait for perfection. Because I have also seen teams really struggle or sometimes fail because they waited until there was something perfect to present, and then you realize that you've built the wrong thing. So I do want to transition and talk a bit about the show because it's our last episode, and we should talk about it, and the fun adventures that we've had and some of the things that we've learned or things that we're feeling in the moment. So given that it's been a wonderful three years for me, it's been four years for you since you've been a host on the show. How are you feeling? CHRIS: I'm feeling a bunch of different things sort of all at once. I am definitely going to miss this immensely. Particularly, I loved when I started, and I got to interview a bunch of thoughtboters and other people from the community. But frankly, three-plus years of getting to chat with you has been just such a delight. There's been an ease to it. We kind of just show up and talk about what we're doing. And yet there are these themes that have run through it. And it has definitely helped me hone and shape my thinking and my ability to communicate about what I'm thinking. I've learned that you have a literal superpower to remember the last thing that you were talking about. Listeners, you may not know this, but we are not quite the put-together folks that we may sound like in these recordings. We have a wonderful editor, Mandy Moore, who makes us sound so much better than we are. But we'll often pause and stop and then discuss what we want to talk about next. And Steph always knows the exact phrase that she or I left off on. And it has been so valuable to the team. But really, it's been just such a pleasure getting to have these conversations. It's also been something that has just gently been in the back of my mind at all times. And so, I'm observing the work in any given week as I'm doing it. It's almost like meditation in a certain way, whereas I'm working on something, like, oh, this is actually really cool. I want to take a note about this and talk about it on The Bike Shed with Steph. And having this outlet, having this platform to be able to have those conversations and knowing that there are people out there is fantastic, although it's very weird because really, every one of these recordings is just you and I on a video call. And so there is an audience, I'm pretty sure. I think people listen to the show; I don't know, occasionally they write in, so it seems like they do. But at the end of the day, this really just feels like a conversation with a friend, and that has been so valuable to have. And yeah, I'm definitely going to miss that. It's been a wonderful run, you know, four years is a long time. It's about as long as I've done most things in my career. And so I'm very happy with what we have done here. And there's a trite saying that isn't...yeah, whatever; I'll just say it, which is, "Don't be sad that it's over. Be glad that it happened." And I guess I'm still going to be sad that it's over. But I am so glad that I got the opportunity to do this, that you joined in this adventure and that we got to chat each week. It's been really delightful. STEPH: I really liked how you refer to this as being a meditative state. And that is something that I have certainly picked up from you and thoroughly enjoyed that I have this space that I get to show up and bring these ideas and topics and then get to talk them out with you. And that has been such a nice way to either end the week or start a week. I mean, it doesn't matter. Anytime that we record, it's this very nice moment of the week where we get to come together and talk through some of the difficulties and share our stories. And that's been one of my favorite moments is because you and I get to show up and share everything that's going on. But then when someone writes into the show or if they send a tweet or something and they share their story or their version of something that happened, or if they said that we made them laugh, that was one of my favorite accomplishments is the idea that something that we have done was silly enough or fun enough that it has brought them joy and made them laugh. So I, too, I'm very, very much going to miss this. It has been a wonderful adventure. And I thank you for encouraging me to come on this adventure because I was quite nervous in the beginning. And this has definitely been an aspect of my life that started out as something that was very challenging and stretching my limits, and now it has become this very fun aspect and something that I get to show up and do and then get to share with everyone. And I do feel very proud of it, very much in part to Thom Obarski, who was our initial producer and helped us have that safe space to chat about things. And now Mandy, who keeps the show running smoothly and helps us sound our best week to week. So it's been a wonderful adventure. This is going to be hard to let go. And I think it's going to hit me most. Like, this was one of those things as we're talking about it, it's, like, I'll see you next week. This will be fine. But I think it's going to hit me when there's something that I want to talk about where I'm like, oh, this would be great to talk about, and I'll add it to The Bike Shed Trello board. And I'll be like, oh yeah, that's not a thing anymore, at least not quite in the same way that it was. CHRIS: So what I'm taking away from this is that you're immediately going to delete my phone number the minute we hang up this call and stop recording. [laughs] STEPH: Oh yeah. I preemptively deleted. So that's already done. Friendship is over at this point. CHRIS: That's smart. Yeah, because you might forget otherwise in the heat of the moment as we're wrapping this whole thing up. STEPH: [laughs] CHRIS: But actually, on that note, in a slightly more serious vein, again, there's this weird aspect where the audience is out there. But we're very sort of disconnected, particularly at the moment in time where we're recording. But it has been so wonderful getting various notes from listeners, listener questions, but also just commentary and the occasional thanks and focusing; oh, you pointed me in the direction, or you helped me think through a complicated piece of work or process a problem that we were having. And so that has been just so, so rewarding. And one of the facets of this that has been so interesting to me is being able to connect to people and basically put out there what we believe about software, and for the folks that resonate with it and be able to have that connection instantly. And meeting people, and they're like, "Oh, I've listened to The Bike Shed. I like all these things." I'm like, oh, cool, we get to skip way further into the conversation because I've already said a bunch, and you say you like that thing. So, cool, we're halfway through our introductory chat. And I know that we agree about a bunch of things, and that's really wonderful. And frankly, I'm going to miss that immensely. So for anyone out there who's found something valuable in this, who's enjoyed listening week to week, or perhaps even back to Upcase for things, I would love to hear from you. I'd love to connect to folks. Send me an email, Twitter. I'm on all the places. I'm Chris Toomey in various spots or ctoomey.com on the internet. Chris Toomey on GitHub. I'm findable, I think. Chris Toomey developer will probably get you there. But I would really love to hear from folks, to connect to folks, you know, someday down the road; I think I'll be hiring again. And that'll be fun. I would love to work with some of the folks that have listened to this show or meet you at a conference, or if I happen to be traveling to a city or you're traveling to Boston. Really for me, so much of what this show is about is connecting with people around how we think about building great software. And so, I would love to continue that forward into the future. So yeah, say hi, if you're interested. STEPH: I agree. That's been one of the most fun aspects of being co-host of the show. And I'll be honest, you are welcome to contact me, but I am going to be off-grid for probably six months. [laughs] So just know that there will be a bit of a delay before you hear back from me. But I would definitely love to hear from you. I also want to say a very heartfelt thanks to a couple of people, just folks that have made this journey incredible and have made it so much fun. One, in particular, is everyone at thoughtbot for their continuous stream of knowledge. I mean, frankly, my software opinions wouldn't be half as interesting if it wasn't for everyone at thoughtbot constantly sharing their knowledge and being a source of inspiration. So I deeply appreciate everyone that has contributed to topics and ideas and just constantly churning out blog posts because those are phenomenal. And I also want to give a shout-out to my husband, Tim, because he has listened to The Bike Shed for many years and even helped out with a number of show notes when that was something that you and I used to do before Mandy made our life so much easier and took that over for us. And has intervened a number of times when Utah mid-recording would decide it's time to play. So I want to give a very special thank you to him because he has been a very big supporter of the show and frankly helped me manage through a lot of the recordings for when I had an 80-pound dog that was demanding my attention. CHRIS: I think continuing on the note of thanks; similarly, I'm so grateful to thoughtbot as an organization for everything that is represented in my career. It's a decade-plus that I have been following and then listening to the podcasts and then joining the organization, and then getting so many wonderful opportunities to learn about this thing called web development. And then, even after I left the organization, I was able to stay on here on The Bike Shed and hang out and still chat with you, Steph, which has been really wonderful. So thank you, thoughtbot, so much. Thank you to Joël Quenneville, who will be the continuing host of the show. This show is not going anywhere. And, Steph, you and I aren't really going anywhere, but we won't be around anymore. But we are leaving it in the very, very capable hands of Joël, and I'm super excited to hear the direction that he takes it and Joel's incredibly thoughtful and nuanced approach to thinking about programming and communicating. So I think that will be really wonderful. And lastly, I definitely want to thank Derek Prior and Sage Griffin, the two original hosts of this show, who really produced something wonderful, and for many years, I think it was about four years that they hosted together. I was an avid listener despite actually working at the company the whole time and really loved the thing that they produced and was so grateful that they entrusted me with continuing it forward. And hopefully myself and then with the help of you along the way, we've...I think we've done an okay job, but now it is time to pass the torch or the green lantern. That's the adage I've been going with. Gotta pass the lantern, pass the mantle on to the next one. So, Joël, it's going to be in your hands now. STEPH: Yeah, I'm so looking forward to future episodes with Joël Quenneville. They are going to be fabulous. So I've been thinking in terms of this being our finale episode and then a fun ending for it, so there's a thing called the 21-gun salute, which is the military honor that's performed by firing cannons or artillery. Not to be confused with the three-volley salute, which I definitely confused earlier that is reserved and used at funerals, which this is not. So using the 21-gun salute, I was like, hmm, it is The Bike Shed, and we have this cute ring ring that goes. So I think for our finale, we should have a 21-bell salute as we exit the shed and right off into the sunset. CHRIS: I love it. I couldn't imagine a more perfect send-off. So with that, what do you think? Should we wrap up? STEPH: Yes, but I have one more silly thing to add. I've thought of a new software idiom that I'm excited about. And so, this may be my final send-off into glory that I'd like to share with you. And I think that we should make like a shard and split. CHRIS: [laughs] I so appreciate that in this moment, this final moment that we have together, you choose to go with a punny joke. It is so on brand for the show. It is absolutely perfect. And I think with that note, shall we wrap up? STEPH: Let's wrap up. CHRIS: 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 hosts@bikeshed.fm via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeeee!!!!!!!! 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:Airbrake: Deploy fearlessly and fix bugs faster with Airbrake Error & Performance Monitoring. Airbrake notifiers are available for all major programming languages and frameworks, and install in minutes, with an open-source SDK-based install and near-zero technical debt. Spend less time tracking down bugs and more time developing. Visit Frictionless error monitoring and performance insight for your app stack.Support The Bike Shed
undefined
Aug 9, 2022 • 40min

349: Unpopular Opinions

Steph and Chris announce Joël Quenneville as the new host of the show! 🎉 Joël talks about his grand plans for where The Bike Shed is going to go from here. (Okay, maybe not grand plans...!) Together, the group chats about unpopular opinions and hot programming takes. This episode is brought to you by Airbrake. Visit Frictionless error monitoring and performance insight for your app stack. Follow Joël on Twitter! Welcome him to the show. Joël Quenneville - DRY is harmful for intermediate devs Become a Sponsor of The Bike Shed! Transcript CHRIS: Thank you. No brown M&M'S. No asking me weird questions. I ask very little. STEPH: 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: I'm Chris Toomey. JOËL: And I'm Joël Quenneville. STEPH: And together, we're here to share a bit of what we learned along the way. So, hey, Chris, what's new in your world? CHRIS: What is new in my world? There is a new friend on the show with us today, Joël, developer extraordinaire, principal developer at thoughtbot, former coach of the Chicago Blackhawks (That one's not true, but it's funny to say.) and friend of the show, many time guest. Joël, so great to see you. How are you today? JOËL: I'm excited to be joining the show. CHRIS: Fantastic. So Steph and I shared with the audience in the previous episode that we have decided...we've made the heavy decision that it is time for us to hand over the hosting mantle. But we had yet to discuss exactly where that was going to go. And today, we are happy to share with you the specifics of that, which is that Joël will be taking over the hosting detail. So, Joël, do you have grand plans for where The Bike Shed is going to go from here? JOËL: Maybe not in grand plans, but I'm definitely already planning content, lining up a few guests. I think the next few weeks are going to be a lot of interviews with some guests, a lot of co-workers at thoughtbot will want to share their stories or some exciting things that they're working on, things they are specialized in. One thing that I really appreciate at thoughtbot is that we're all pretty full-stack developers. Everybody tends to have a specialization or an area they're really good at. And so when you're ever stuck, and you need advanced Git help, you go to, historically, Chris. If you want some help on security, you go to Mike Burns, et cetera. And so yeah, I'd love to bring in some of them and get to talk a little bit about some of the areas where they're either doing something interesting, or this is just an area where they have deep expertise. STEPH: I have to say that having you take over as host of the show feels like such a nice continuation, given that you've been involved with The Bike Shed since you were a guest on the show back in 2018. And then, since then, you've been a repeat guest. And even when you're not here, Chris and I still frequently bring up your name and mention some of the talks and the blog posts that you have written. So I'm super excited for everything that you just said, for all the guests that you're going to bring on the show, and the thoughtbot voices. And I'm looking forward to tuning into future episodes and hearing what happens next. JOËL: Yeah, this is a really exciting transition for me. I am a long-time fan of the show. I've been a guest a few times. And now, coming on as a host is just taking it to the next level. CHRIS: Yeah, Joël, I'm also super excited to see the new perspective that you bring to the show. And frankly, to Steph's point, you've been on the show a bunch of times. You've been here in spirit. In fact, there was a tweet that someone sent to us which was "Hey, @joelquen," which is your Twitter handle, "I feel as if I know you and your work after listening to @SViccari and @christoomey. They definitely appreciate you," which was true then and is true now. So I couldn't be happier for you to be taking over this hosting slot. JOËL: Creating content for developers and sharing the things I've learned, or the things that I've experienced with other people has always been something that's been really important to me. And so, getting a chance to bring that to The Bike Shed is a really exciting opportunity. My past work has intersected with the show several times, either that's been conference talks or blog posts, or even just conversations we've all had. Steph and I pair almost every day. So there are a lot of good conversations. A lot of conversations that end with me saying, "You should talk about that in The Bike Shed. That's a good topic." STEPH: You have been an excellent source for topics in terms of you've literally added stuff to our Trello board that we use to manage the show and then yes, and all those conversations that we've had. You're like, "Oh, this will be a good Bike Shed topic." And I'm like, "Hold please," while I go and then add it to our board. JOËL: The fun of being an employee at thoughtbot is that I have access to the Trello board. And I can just add whatever ideas I have there for you all to talk about. [laughs] CHRIS: That is the most direct way to send in a listener question is just to write it into the Trello board directly. Skip all the forms, and the Twitter, and the whatnot. JOËL: Yeah, speaking of topics on our Trello board, let's go out on a really spicy one. I see we have a card about unpopular opinions. Chris, you created this. What is your hot programming take? CHRIS: This was so long ago, I don't even remember. But this one has interestingly sat on the Trello board for a while. I was like, Steph, let's really lean into it. Let's go out there. What are our extreme takes? And I think we say the stuff that's in our heart most of the time anyway. But we're; also, I don't know, pragmatic, kind of boring up the middle. Someone recently described my tech choices as like a Subaru. Like the architecture, the way I built it, you know, it's stable. It'll get to where you want to go. It's not going to be too fancy or too flashy. And I was like, you know, actually, humorously, my wife and I just bought a Subaru. So I was like, I guess I can't say no to that. Anyway, though, I think I have one spicy take, which I have shared on The Bike Shed before. But it is the thing that I will die on this hill. I care about this. It feels like I'm just being persnickety, but I think it matters, which is that the phrase single-page application or the idea of an S-P-A or a SPA, which I've heard some people say it, is just a terrible framework. I am so unhappy with it as a concept. I think, technically, the implementation of them has often led to some really complicated things, which is why I've spent so much time exploring Inertia, or LiveView or Livewire, or all of the other options that are out there. I think there are some really interesting novel ways. Remix.run is the most recent thing that I've been talking about, which takes a pretty traditional SPA type of build and then makes it behave more like a traditional server-rendered application. But just the idea single-page application really grinds my gears that that is a thing that we talk about. Because it's the web, we have URLs; these should all be different pages. I don't care if there's one bundle of JavaScript that we send down or that it begins as a single HTML file that we send down, and then we repopulate constantly. There still should be URLs. Those are a honkin' good idea, and we should use more of those. And we shouldn't anchor to a technology...like, no, SPAs, I don't like it. I'm not a fan. So that is my unpopular opinion, I'm pretty sure. STEPH: I think we have a full episode, too, where we focused a lot on that topic where you shake your fist at the SPAs in the world [laughs] and why you don't like them. JOËL: I feel like the industry pendulum might be swinging back. I think we've hit peak SPA, and now we're slowly moving back, anecdotally anyway. CHRIS: That is definitely what I'm seeing more and more of, and I'm very happy for it. Because I think there's some interesting stuff that came out of SPAs and the ideas of like, oh, let's animate, and let's have more continuity and page transitions and things that I think can really enhance the end-user experience. But I think the cost has been too high. It's broken us from some of the norm. Like, how does the web work? That's a thing that we should talk about. Links, they're awesome. You can link between pages. It's so cool. And we just kind of threw that away. And we're like, div onclick. It'll be fun. Don't worry about it. Screen readers, who cares about those? Doesn't even matter. I care. That's who cares. I'm going to calm down now. I'm fine. It's fine. But yes, I agree. I do think the pendulum is swinging back, and I'm very happy to see that. JOËL: Long-time listeners of the show will know that I'm a big fan of the Elm language. And for the longest time, I wanted to do a client project at thoughtbot with it. But I agree with you, Chris, that a lot of things shouldn't be SPAs. A lot of things should be just boring Rails apps. And so, every time an opportunity came, I just couldn't justify doing a front-end app. So I would be like, yay, I would love to do Elm here, but this should just be a vanilla Rails app. And then, one day, we had a project that came in that was actually a single-page app. It was one page where you loaded up a bunch of data streams and then could interact with them and get all these cool visualizations and things. There was no clicking away. There were no other pages. It was just load some data, and you've got a playground. And that was the moment I knew, okay, this is the app I want to do in Elm. And that was my introduction to bringing Elm to colleagues at thoughtbot to work on a project together. STEPH: You put out the signal kind of like the Batman signal, but you put out the Elm signal calling everybody into the project. JOËL: [laughs] CHRIS: You put a small tree on your desk, and everyone came together around it. JOËL: [laughs] CHRIS: Also, I want to applaud your pragmatic restraint of I want to use this. This would be fun to use, but it is not the right choice for many particular applications or projects that came through the door. But then you found it. Then you found that magic moment. To be extra clear, I'm not opposed like; my distinction is an SPA or traditional server-rendered HTML generation on the server...I got redundant in there, but that'll be fine. It's more the bundle of JavaScript that goes down and that there's no routing on the server-side, et cetera, that all logic is pushed to the client-side. I've harped on about Inertia and my love for that framework over many, many an episode on the show. But I feel like that, and many other solutions that are in that similar space, allow us to have the sort of experiences that are traditionally associated with an SPA but don't give up on the idea of auth being simply managed via a cookie on the server sort of thing. Cookie on the server is a phrase that doesn't really make sense. But y'all get what I'm saying, I hope. If not, assume that I said the right thing. It'll be more fun that way. JOËL: Steph, I'm curious; what's maybe one of your unpopular opinions or hot takes? STEPH: I have a couple, and since Chris used a phrase that has now helped anchor me in terms of like the hill that I will die on, I'm now looking through that list to pick the one that I feel like the most passionate about. So looking through that list, I might just have to go a couple. It's hard to really choose. But the first one is I'm going to say you don't need a side project. I can't tell you how much that frustrates me when people just always say you have to do something on the side. You have to stay up late and code. You have to do coding on the weekends. I feel very strongly that software development is a job, and it doesn't have to be your passion; if it is, that is fabulous. But it is, at the end of the day, still a job, and you don't need to know three additional languages to be good at your job. And you should be able to focus on learning what makes your day-to-day easier and then learn that during your work hours. So that's something I feel very strongly about. JOËL: Do you think that's something that is a current reality or something that is aspirational? As in, an employer shouldn't require it, or it is currently possible to have a completely fine career and never have a side project. STEPH: I think it's very possible currently and aspirational for some teams. I think there are some companies and teams that will turn you down because you don't fit that mold. And I think that's what then puts us in that unpopular opinion category. Because there are enough people that still think that that is an important part of being a software developer. But I do think that there are still plenty of teams and people that are starting to agree with the idea that it shouldn't be that way and that that is not a requirement for an interview, or for joining the team, or for being a good developer, or for progressing in your skills. So a little bit of both, currently possible and also aspirational. JOËL: I'm going to throw a question out, and I think this may be its own complete topic. So feel free to tell me that this is not the day to talk about this, but I'm going to put a question out. Recently, there was a really good conversation that happened internally at thoughtbot where one of our newer developers was asking, is it possible to progress our whole career ladder without ever doing any side projects? So just 32 hours of client work, eight hours investment time every week. And maybe a little bit beyond that, maybe it's technically possible. But it takes an excruciatingly long time. Is it possible to progress in a reasonable amount of time through the career ladder without doing any extra work outside of our standard working hours? What are your thoughts on that for thoughtbot? STEPH: I think the answer has to be yes. Because I mean, who's creating that ladder that you are climbing? It's going to come down to the company and the managers and the people who are deciding on how you advance, and not everybody has time. So what you're telling me is that if someone can't advance during the normal work hours that they have then...because they have families; they have other priorities in their life; they have other responsibilities, that then they're just stuck? And that feels like an unacceptable answer to me. So my answer is absolutely you can progress during the work hours that you have. And if you can't, then that is a problem for managers and leadership to fix. CHRIS: I definitely agree with the assertion that you're making, Steph. And I like the ire that you're bringing to this. This is good. This is the sort of fire that we should have in this particular segment. I do think there was an aspect of the question that is subtle and really interesting to me, which is in a reasonable amount of time. And then you mentioned, or it might take an excruciatingly long amount of time. A thing that I observe about our industry is that it is rather young overall, and the expectations of progression are incredibly rapid. This is sort of my second career. I spent three years as a mechanical engineer working in industry. That was the first thing that I did. And that world looks wildly different. The idea of achieving principal engineer, which is a little bit more formalized of a concept, but I saw that as 30 years down the road kind of thing, or it may be 20, or something, but a significant chunk of my career. That is something I might achieve towards the end of my career after having put in a lot of time. And development is just such a young industry. Like, the idea of going to a bootcamp and then two years later being a senior engineer and continuing to progress just ever so rapidly is interesting. I don't want to slow anyone down by any means. And I don't want to say that like, well, when I was over there, it was slower, and so it should be slower here. But I don't think it's realistic, frankly. And I think some of what is at the heart of this question is like, no, this is an industry where you get in there, and in five years, you have achieved the pinnacle of your career. And then you go retire, and you go to a cabin in the woods, and you never talk to humans or touch a computer again. That's the dream. It's like, well, maybe that's not realistic. And what would it actually look like if we were a little more chill about these sorts of things? That is a question that I have. STEPH: It's funny that you mentioned that one because that was one that I almost put on my list of unpopular opinions where I think the progression in which we change our titles as developers is silly, [chuckles] is probably the best word that I have for it. Because I agree with you, I don't want to slow people down. And we often change our titles to reflect that, yes, we want more responsibilities. We want more pay, and so that feels like the best way to then achieve those goals. But it's so rapid in how we expect people to progress to different levels of engineering. I do think it loses a bit of its meaning because then we progress people so quickly through those different roles. Because then senior developer means so much. I mean, are you a senior developer with two years of experience or ten years of experience? Like, you could be in both of those groups. And so, it just loses some of its meaning because of that. JOËL: It's also hard because years of experience aren't really a good way to compare two developers. I mean, two versus 10 is probably something you can compare very roughly. But five versus 7 or 5 versus 10, someone might be much more experienced or be better at solving problems after five years than somebody else in 10. CHRIS: I will argue that two years in a consultancy is like five or maybe even ten years in a middle-of-the-road product company that's kind of got its stuff figured out. And just the volume of new and novel that will come at you is quite large. And I strongly recommend working with a lovely company called thoughtbot to get that experience because it'll be a fun time while you're there. And, man, will you learn a lot. MID-ROLL AD: Debugging errors can be a developer’s worst nightmare...but it doesn’t have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help you cut your debugging time in half. So why do developers love Airbrake? Well, it has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake’s debugging tool catches all your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake’s lightweight APM enables developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps and includes modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. So head on over to airbrake.io/try/bikeshed to create your FREE developer account today! STEPH: Joël, I have another potentially unpopular opinion I'd love to share. But I'm curious, what's one of yours? JOËL: So here's a controversial opinion that I have: DRY, Don't Repeat Yourself, is dangerous, I'd say even a harmful rule of thumb for intermediate developers. It's one of our favorite kind of aphorisms, principles that we try to live by as developers. But I think it often does more harm than good at a certain point in your career. When you start off as a new developer, one of the most common sorts of bugs you'll do is where you duplicate code, and then you change it in one place and don't change it in the other. And they're out of sync, and then your code breaks. And then you discover DRY, Don't Repeat Yourself. And it's amazing because this simple rule fixes 80% of the bugs you were creating. And of course, now there are other types of bugs you find out about. But it's a whole class that gets eliminated by that, and it's wonderful. But then you get into the intermediate developer, and you start to get clever, and you try to apply this in a lot of places. And you start trying to abstract things that are similar but not the same, and then they start to diverge. And then you've got a mess on your hands. And this happens in application code happens in test code. Yeah, you end up doing that, prematurely abstracting, and particularly when it's just based on through a simple substring matching. So you're saying this string of 100 characters is identical in two files. We need an abstraction that shares these two when the fact that the two strings might be similar is just coincidental. And so that's where you cause more harm than good. And then eventually, you kind of transcend that, hopefully, and get back to the point where you can maybe apply DRY more judiciously. Now, DRY is no longer for you about similar characters. It's about similar or actually same concepts because similar is not good enough. And hopefully, you have the discernment to distinguish between similar and same. And when you're not quite sure, maybe you leave them separate to see will they diverge in the next few months? STEPH: It's almost like you and I are on the same project, and we have felt similar pains in the world. JOËL: [laughs] I think this is a thing that a lot of developers eventually get to the point where they can do it decently well in production code. But at least when it comes to RSpec code, the Ruby community has just refused to learn this lesson. We're still stuck in that intermediate developer phase where everything's got to be extracted out as shared setup. And I would argue that shared setup on most tests is similar and not same. And the identical thing is if you're just copying two strings of code that look similar in two files and creating an abstraction that really doesn't need to be there. CHRIS: Friends, I have to tell a truth in this moment. I wrote a let within an RSpec file this week. It happened. JOËL: [Gasps] STEPH: This is actually why you're moving off the show, Chris. This right here. [laughs] CHRIS: I'm getting kicked off the island. I've broken rule number one [chuckles]; let's not. This was...I think it was a reasonable one; at least I couldn't figure out a different way to do it. I was defining a class within an RSpec file, a representative implementation of a subclass. And I tried to do it by just defining a class in line, but RuboCop came along; we recently added RuboCop to the app as well. And RuboCop said, no, no, no, you are leaking a constant. And I said, oh, that's true, RuboCop. And then, thankfully, the documentation page for that rule had a pointer to what to do instead. And so it ended up with a let. I don't actually think I need to let now that I think about it. You can dynamically define a class within a spec example. So I then, in the rest of the example, started doing that. So I'll probably remove the one let that I actually added. [laughs] But it happened. JOËL: That honestly seems reasonable to me. I think there are use cases where let can be done correctly. It's just really hard to have the discipline to not stray off that very narrow path of safety. I recently gave a talk at RailsConf about how your test suite is making too many database calls. And most of them are all related to doing way too much during your setup phase. And one of the reasons I gave that this happens too often is shared setup and let in particular. And I thought that I might get booed off the stage. But in fact, several people came up to me afterwards and told me that I had actually given them a whole new perspective they had never seen, and that was interesting to them. STEPH: That's awesome. That's so nice that people came up and shared that with you. Yeah, I think one of the areas that I don't know if we highlight enough, but whenever you and I happen to gripe about the use of let or over drying and extracting setup for tests, specifically, is because then we're not talking about the trade-off of then you're coupling all your other tests to that extracted setup. And so it's not so much that I care that you dried up your test setup, and now the rest of my tests are likely reliant on that extracted shared setup. And then that's where we've introduced a trade-off, and it's a painful trade-off that I have worked through a number of times. So just to add a bit of persnicketiness to our discussion in terms of it's not so much the DRY in the extraction that bothers me, it's then the trade-off of now everything is coupled. And it becomes much harder to then create independent scenarios that are still easy to read and then modify. JOËL: Because you're coupling two things that are not the same, that want to diverge. And now you're forcing them down a single path. And I think probably the biggest, reddest flag you can get that you've misDRY-ed is where you try to introduce conditionals to your shared extraction. Because the whole point of a shared extraction is that everything is the same. And so once you start introducing branching in there, you know something's gone horribly wrong with your abstraction. STEPH: Okay, so I think we've established that we've got very strong, maybe popular, unpopular opinions about DRY and especially using DRY in test setup. What's another unpopular opinion that you have, Joël? JOËL: This one is a stylistic one. But I think that in Ruby, at least, every if should come with an else. You want something to happen when your condition doesn't trigger. I think it generally makes for more readable code and also prevents some implicit nils from getting through. And nil errors are probably at the top of your bug backlog if you were to look at right now (For all of you listeners, I'm pretty sure that's true.), excluding JavaScript. CHRIS: Someday, we're going to make undefined a function, and it's going to be a great day. This is an interesting one, Joël. I'm inclined to agree with you, but I know that in my code, I don't necessarily follow this adage. So I find it interesting. I would call them intentional nils; I'm sometimes fine with that, or particularly in side effect-y code, you know, if this condition, then do something, otherwise, nothing. But yeah, it is interesting. The explicitness, the nil, is a big mistake that seems true. You hang out in Elm for long enough, and you don't have one, and then you got to think about stuff harder. But yeah, I don't find myself doing this. So I find it interesting. I conceptually agree with what you're saying, and yet my code tells other stories. JOËL: So I would argue that Ruby is an expression-oriented language; all methods auto return something as opposed to a statement-driven language like JavaScript, where nothing returns unless you explicitly return it. Ruby is all about those return values. And so you need to cover all branches, and if you don't, Ruby will implicitly have some branches that you don't have there. And so, I prefer to make visible the branching logic that's happening. STEPH: I also like this one. I think I'm on the same page as Chris, where I like the opinion and this statement. And then also, you'd asked me earlier about whether something is capable now versus aspirational. And this feels like in the aspirational area for me where I agree with it, but I don't necessarily do it. But I think it makes a lot of sense because then it does force you to think about what is the return value? And to be very explicit and say, yep, no, I want a nil here. That's just what I'm going to return. JOËL: And maybe even think about in that else case maybe you don't always want nil, maybe you'd rather return an empty string, or a null object, or something like that. And forcing you to actually manually type that value in instead of just being like yeah, Ruby knows. It'll put a nil there. It's easy to not think about the error edge cases, which I know is the opposite of how Chris thinks. Chris thinks about all the error edge cases. CHRIS: My brain has been shifted by experience. JOËL: One thing that I think this works really well is a stylistic approach that I use where I separate branching code from doing code. So in a particular method, if there is a conditional, then the body of the conditional calls out to another method. It doesn't implement logic there directly. And if a method does a calculation, or does the side effect, or does some kind of work, it's not allowed to have a conditional in it. So an individual method either gets to branch, or it gets to do a thing but not both. STEPH: Is that so you can quickly see all of the branching that's involved so you can see it at a very high level versus if you have a very large branching in your method and then it's hard to see how many possible return values that you have? JOËL: Yes. I like it because when you read code, especially when you're reading code that has a conditional in it, typically, you're reading it at a higher level of abstraction. You just want to know what are the possible ways that it can branch, and then what are the paths it can go down? And you probably don't care about all the nitty gritty implementation details that happen at each branch. And then you might care about one particular branch and decide to go down that path. At that point, you will jump to that method. But you don't need to have all 2 or 3 or 10 branches expanded for you. It keeps the method at a single level of abstraction and also allows each method, in a certain extent, to have a single responsibility. It does one thing. It's either branching between n choices, or it does one thing, but it doesn't try to do multiple things. So that's less of a hot take opinion, like, everyone should write code that way. That's just a style I've adopted for myself that works really well. But that particularly dovetails nicely with my hot take, which is if should come with an else. STEPH: I like it. JOËL: Yeah, so, Steph, do you have another juicy opinion you'd like to share with our listeners? STEPH: Yeah, I've got one more to share, and this one is going to show my consulting roots. And it's that developers should be included in the design and planning phases, and not just in the execution phase of the work. So that's something that I've seen a number of teams struggle with where they wait until either design is considered completed or perfect or someone else has figured out the way that they want a feature to be built, and then they just essentially throw it over the wall and kick it over to the development team. And so then it's laid out with very specific criteria. But it's not clear the problem that's actually being solved. And so developers have done a very narrow focus of what they're working on. And you just often end up building the wrong thing when that happens because people don't have the context. They don't know the questions to ask if they do run into some questions regarding the requirements. And so I strongly advocate that developers shouldn't just pick up tickets and then write code, that they should be part of the planning and the product process as well. Turns out that developers often have really good ideas when it comes to features. And they also have a lot of knowledge about the application and can ask good questions. So why not include them in that process? JOËL: You mentioned that this is inspired by your experience as a consultant. I've sometimes heard the contrast between the terms contractor versus consultant. Is that a distinction that you make? STEPH: Yes and no. Yes, because I've heard other people make that distinction, but I personally wouldn't make that distinction. And even for people who are not a contractor or consultant but they're full-time, I still love when people can adopt the mentality of you have the same responsibility of this product and where it's headed and its technical decisions. And we all should be mindful of the time that we're spending as we're working on something. And I think being a consultant helps you be more mindful in terms of like, oh, I've spent two hours on this problem. I should probably reach out for help. And I feel like people who haven't had an opportunity to be in that mindset don't think that way. But I think it's a really wonderful state to be in all the time just to think through; okay, I've been stuck for an hour, now's the right time that I should reach out for help. Versus spending like a full day on something and then reaching out for help. So I have heard that distinction, but I personally wouldn't make that distinction. I would advocate that even if you are a consultant, or full-time, or contractor that ideally, you would still be part of those different processes to then help build a valuable product. JOËL: Steph, I found it really interesting when you introed this idea. It was about developers bringing their ideas to the business and design side of things. But then, when you dug into the idea a little bit more, you kind of flipped it on its head and said that being involved in those meetings helps developers do their job better because now they can more appropriately timebox a feature or decide when they've hit that 80% point that's good enough to ship, and then they need to reprioritize something else. So it sounds like there are advantages to both sides, both the business side and the dev side, from a tighter integration there. STEPH: Yeah, thanks for calling that out. I think that's an excellent point that I hadn't really even considered as I was just rambling about a strong feeling. But yes, I think it's beneficial to all sides. It's beneficial to developers who are getting the work done. And then I also think it's really beneficial to the product team and design just because that way, everybody essentially has the same context. They're on the same page. And then you also have more camaraderie that way too in terms of people know the problems that they're trying to solve. And you can have more opinions. And people can surface those ideas versus if you are kept in the dark as to perhaps why a feature is being built or who it's geared towards, then it's more likely that you're not going to be as connected with the rest of the team and be able to provide helpful ideas because you won't have the fuller context to then surface that to the rest of the team. So this is definitely coming just from all of my experience in the projects that I've been on that the most successful projects include design, and developers, and product management. And they all get together, and they talk about the problems that are being solved. Versus the projects that I've been on where essentially, all of that work is done separately, and then there's just a Trello board or Jira tickets or whatever tool that you're using. And then developers go and pick up tickets. Because then you often end up having those discussions anyway because developers are then going to have to check in to say, hey, you said this thing. Did you mean this? What exact requirements am I looking for? By siloing that process elsewhere, you end up just duplicating your efforts because that conversation is ideally going to happen anyways. JOËL: I recently had a conversation with someone who had been promoted to senior developer and was asking me for some advice on how do you be a senior at your job. And this is at a product company. And basically, what you were saying, Steph, is what I recommended. If, as a senior developer, you are just a machine that converts tickets into code, they're not using you to your full potential. And honestly, they're overpaying for what they're getting. You need to be in those meetings, in those conversations, so that, as you mentioned, you can be that nexus between business and tech and tell them, look, this is your strategic goal. You think this is the technology thing you want to do. Yes, it will solve your problem, but it will take twice as long. And that is incredibly valuable to the business people because doable and easy, and very similar solution that is near impossible to do in tech are very common. There's a classic xkcd about this situation. And so having someone who knows that nuance and can recommend and say, look, we can do this in two weeks. That will take six months. Or even just talking through trade-offs is incredibly valuable. And then, as you said, bring that back in your own work, knowing when to say, look, we thought this is going to take two weeks, and it's taking more. We think this is going further. We know that the business goal is to get to here. So I'm going to pause on this and propose a different technical solution that will get us most of the way towards that goal while still respecting the deadlines we're working under. I might argue that this sort of mindset is not just a senior developer thing. It's valuable at mid-level and junior as well. And I think that as a consulting firm at thoughtbot, that's something that we bring in from the beginning for everyone that we try to build this. But definitely, as you move up into your career, this is going to become more and more important. CHRIS: Yeah, I'm surprised. I'm actually totally on the opposite side of this one. I fundamentally disagree with...no, I totally agree with everything you're saying and how important these sorts of conversations are. We're actually working on something at Sagewell right now. It's a new, reasonably large integration with an external platform. And we're very, very intentionally pushing such that product and design are going off and doing some work, and engineering is going off and doing exploratory what do the APIs actually look like? What's the data that we need? What's the object model in this system? What can we get away with not providing? What do we need to provide? And continually, we're just trying to encourage communication across those different tracks. So design is thinking about different flows and what's the experience a user is going to have. And ideally, getting engineering to review that and say, "Oh, that's going to be easy. That'll be hard. I think we could do that, but I actually have to go look it up and see if that's possible," and vice versa. Engineering now being in the depths of saying like, "Oh, actually, this has to be done in this way for legal reasons or whatever it is," and then providing that back to design and product to think about how do we structure it? How do we sequence things? What's part of the MVP? And I've been really happy with the nature of that, that back and forth communication. But it is definitely something that requires intentional work of making sure that we're not just falling into our own silos, but we're coming up for air, having those conversations, passing ideas back and forth, including each other in the conversations. But without question, it will produce a better outcome at the end of the day. So yeah, I actually do, in fact, agree 100%. STEPH: Yeah, to add on to that just a bit, there is a particular example that comes to mind where I felt the most pain for when developers and product and design aren't in the same room and then discussing the work to be done. And that's essentially where someone ends up building the wrong thing. And it's because someone decided that they knew the best solution for something, but they didn't really collaborate with the rest of the team. They turned that into a ticket. So then a developer sees that, and then they start implementing, and it's not until later that someone comes along and starts asking questions to say, "Hey, so what problem are we solving?" Or "Why are we adding this code?" And Joël, I think you said it perfectly and that this is something that I do expect of a more senior developer where they have that experience, and they ask those types of questions that then you realize that, oh, we've actually built the wrong thing, or the thing that we're building doesn't solve the problem that we had in mind. And at that point, you have someone who has invested a week, maybe a couple of weeks into something, so then that feels really terrible to then say, "We actually need to scrap this" or "We need to totally rethink this." So then you start making trade-offs of like, well, maybe we can keep this portion or preserve some of the work that you've done. And so you just end up in a really messy state. And that can be avoided if people are collaborating at an earlier stage of that process. JOËL: Yes, you and I, Steph, were in a very particular situation where something like this had happened. Some developer had been working on a ticket for a couple of weeks. And it was one of those tickets that just kept growing. The code kept growing, but then the client kept adding new requests and features onto it. And then, at some point, you and I were brought in to help, and the first thing we had to do is like, let's stop and ask what is the problem that is actually being solved here? And actually got everyone together with the client. And that conversation helped us do a big reset and helped us find a way that was more focused that actually solved the underlying problem, what the client actually wanted rather than what they said they wanted. I noticed that for most of these unpopular opinions, it sounds like we pretty much all agree with each other. So either we all have a very similar set of unpopular opinions, or maybe these opinions might be a little bit more mainstream than we give them credit for. I find that oftentimes, at least on Twitter, when people tag things as "unpopular opinion" in quotes, they may be a little bit more popular than people give credit for. CHRIS: I feel like the RSpec one is unpopular. And also, have you asked Steph about Pop-Tarts? JOËL: [laughs] CHRIS: Because we are capable of having sincerely unpopular opinions. JOËL: Let's save that for the next episode. And on that note, shall we wrap up? CHRIS: 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 hosts@bikeshed.fm via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeeee!!!!!! 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:Airbrake: Deploy fearlessly and fix bugs faster with Airbrake Error & Performance Monitoring. Airbrake notifiers are available for all major programming languages and frameworks, and install in minutes, with an open-source SDK-based install and near-zero technical debt. Spend less time tracking down bugs and more time developing. Visit Frictionless error monitoring and performance insight for your app stack.Support The Bike Shed
undefined
Aug 2, 2022 • 32min

348: Breaking News

Steph and Chris share some big news about the future of The Bike Shed. Steph shares an update about integrating with Knapsack Pro. Chris is excited for larger projects that will begin in the next few weeks. They answer a listener's question on keeping backlogs connected to the product vision. This episode is brought to you by Airbrake. Visit Frictionless error monitoring and performance insight for your app stack. Linear RailsConf 2022 YouTube Playlist Become a Sponsor of The Bike Shed! Transcript: CHRIS: We don't need Skype anymore. We live in a post-Skype world, audio flapjacks. Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Chris Toomey. STEPH: And I'm Steph Viccari. CHRIS: And together, we're here to share a bit of what we've learned along the way. So, Steph, what's new in your world? STEPH: Hey, Chris. So let's see, recently, Utah, who's my dog for anyone that's not familiar, Utah had his very first beach trip. So we went down to Myrtle Beach area in South Carolina. And he had a grand old time because he's a water baby. Like, if there's water, he is in it. He loves it. So I was confident that he was going to like the beach, but I wasn't sure what he was going to think of the waves. And luckily, there's an inlet area so that he could splash around and not be too worried about waves and had a wonderful time. He did take a huge gulp of saltwater because he's not used to that, and that threw him for a loop for a while. [chuckles] But overall, it was a lot of fun. He had a wonderful first time at the beach. CHRIS: A live raptor on the beach. For continuity for anyone listening, I tend to call Utah Raptor because there are things called Utahraptors, and I can't call things by their normal name. It's just an affliction I have. But yeah, a raptor on the beach. STEPH: He has a couple of nicknames going for him. There's someone else in my family that always refers to him as Tank; I think because they remind him of another dog named Tank. So yeah, he's got all the nicknames. In some more tech-related news, I'm super excited that the Rails conference talks are now public. There are a number of talks that I'm interested in watching. And there's just such a killer lineup of topics and presenters, including a number of thoughtboters that presented this year. There are also several talks that focus on testing legacy code, which, as you know, is very relevant to my life right now. So I'm particularly interested in those talks. And frankly, I'm running out of doomsday movies to watch. So it's really good timing that I have these talks to help with my evenings where I need something to watch. CHRIS: Now you say you're running out of doomsday movies, but have you watched Armageddon? STEPH: [chuckles] No, it is on the list. So I have not completely run out. I have a very good one to still watch. CHRIS: I'm not even that big a fan of the movie. It's just now a part of my public persona, apparently, and so I got to hold that line. But I didn't realize the RailsConf talks were out. That is super exciting. I will definitely have to check through those and pick out a few at a minimum, watching all of the wonderful talks by thoughtbot folks. So yeah, that's very exciting. STEPH: Yeah, I'll be sure to include a link in the show notes so that way it's easy for folks to find and watch along. You and I also have some big news to share with everyone. As most listeners know, I've been prepping for maternity leave. And as part of that preparation, you and I have discussed ways to handle that period where I'm away and focused on being a new mom for six months. We talked through a couple of ideas, and ultimately, you and I came to the conclusion that the timing feels right to end our season as host of The Bike Shed and transition the show to a new host, so a passing of the torch or a passing of the handlebars if you will. So even though you and I are leaving the show, The Bike Shed will continue to exist, and you and I will be here for the next couple of episodes. And the show will continue to be the wonderful show that it is today. And we'll share some more details about that in a future episode. So while it's really exciting that someone new is going to take over the show, I think I can speak for both of us when I say that this definitely wasn't an easy decision. I know that I've really enjoyed this part of my life where we show up and share our development adventures. Although, to be honest, it's really all the nonsense; that's what I'm here for. That's been my favorite part, like our poor attempts to use sports analogies and renting goats to mow the grass. And I particularly love when you lean into segments about what grinds your gears. There's something about a spirited Chris Toomey "You know what grinds my gears?" rant [laughs] That really brings me a lot of joy. CHRIS: Oh, well, that feels like it's too kind of a thing for you to say. And, well, this is already an emotional topic now. I'm feeling the feels. But yes, this has been such a joy to record the show with you. And again, we'll be here for a couple more episodes just to sort of segue over and provide some continuity. But yeah, it is, I think, the right time. We've both done this for a good bit of time now. I think we've said a lot of the things that we have to say. I appreciate both the consistency in what we've had to say and also the way things have changed and the new elements that have come in and out. But yeah, I am excited for the next host, and we will introduce you to them in the very near future, dear listeners. At a minimum, and we'll get another chance to say this, but, Steph, it's been a real pleasure recording this podcast with you. STEPH: Thank you. It has been a real pleasure. And I'm with you, this is hard to do, and it's hard to announce. But like you said, we'll have some more episodes, and then we will also have more of a finale episode where we can dig into all the feelings. But keeping some of those feelings at bay for now just because we will still have a couple more episodes to chat and then another episode where we can really dig into all of those feelings and then also reflect on our time as host of the show. But returning to a technical note, I have an update I can share that's related to some of the testing work that Joël and I are doing. Specifically, we started integrating with a service called Knapsack Pro, which is a service that helps you parallelize your test suite across CI nodes to then speed up your test suite. And ultimately, what we really want to use are Knapsack Pro's cue mode and automatic splitting of large test files to help us then distribute those files across all of the available nodes. And we're still working on setting that up. So I don't have any cool or sparkly stats to share just yet. But I have noticed some other wonderful features about Knapsack, specifically some of the reporting structure that they have. So a lot of this data Joël and I were collecting manually. So we were having to go through and figure out, okay, how long are test files taking? Which files are running on which process? Where do we have, like a tentpole, a particular file that's taking a lot longer than other files to run? And with the Knapsack UI, they're just telling us all of that data where they're showing us how long do the test files take? Which process is completing first versus completing last? They also show what's the time span between the finished times of the CI node that started first versus the one that finished last? So we can see like, are we balancing well across all of these nodes or workers? So there's been already a lot of really good stuff that I've been seeing from Knapsack Pro that I'm really excited about. And we'll just have to see what comes next with the queue, what kind of time improvements that we can also see by taking this approach. CHRIS: Oh, that's cool. I didn't realize you had started working with Knapsack Pro. That's definitely on my short list of things to consider, particularly as our test suite grows. Actually, on a quasi-related note, we this week had another developer who had been off for a couple of months in the summer; they just came back this week. And so we're sort of at full capacity. And I've also been writing a couple of PRs this week. It's been exciting. I actually still remember how to code, which is cool; glad that that's still in there. I'm actually operating as point dev this week, which means that I am the support for our admin team wherever they need changes to customer accounts or things like that happening in the background. I'm also triaging all the bugs and things that are coming in, so there are a bunch of little PRs that I pushed through. But interestingly, I've just not really looked at or optimized our CircleCI plan. But we keep going over our budget. And then it turns out that their pricing is structured in probably a reasonable way where we buy a plan that is this many build minutes for a month or this many build points or whatever it is, and we keep going over. And each of the overage charges are actually kind of expensive. And we're now doing it on a weekly basis which is I should probably rethink some stuff, figure out a more optimum strategy there. But there's a certain pride of like, oh yeah, look at us. We're burning through CI, really making a lot of PRs happen. But I do remember there was a particular week where one of the developers was on vacation; somebody else was elsewhere. And so, our throughput on engineering dropped significantly. And we got this email from CircleCI. It was an automated email, but it was like they were negging us and they were like, "Hey, do you need some help unsticking your CI pipeline? Looks like your build minutes have dropped way down." And I was like, whoa, CircleCI, I do not like the vibe that you're putting out there. So now there's this perverse pleasure in like yeah, that's right. We keep going over our limits, and then you charge us a bunch. But actually, I think you're winning in all of these cases, never mind [laughs] I'm just losing. But yeah, it was a fun sequence of emails from CircleCI. STEPH: [laughs] That's one of those are you okay? Kind of emails that you get from a service. [laughs] That is fascinating. And yes, I think they're winning because they have then encouraged you to keep it up in terms of like the spend. You made me just think of one of the nice features that we've also noticed with or not so much a feature, but it is a process that they have with when you start your free trial with Knapsack to then integrate and see what the results look like. I believe it's 14 days that they give you. But those 14 days only count for build time. So it's not just like from the day that you sign up to now you've got 14 days or business days; it is specifically allocated to the days that you're actually running builds. So I don't think they break it down in terms of hours worth of 14 days. But it's like, hey, did you run a build today? Then we'll calculate that. Which has been nice because then there have been some side adventures that we've been interested in, and we've been allowed to pursue those side adventures because we know we can pause on Knapsack for just a little bit, but we're not going to lose that day as part of our free trial. Their customer support has also been really nice where they've already...because Joël has been chatting with them with a couple of questions, and they've been very nice with like, hey, we know there are some issues that you're working through in terms of getting the cue mode up and running. So if you do need a couple of extra days, let us know. I wonder if Knapsack Pro will be cool with me sharing that inside baseball, but [laughs] their customer service has been very helpful and nice in that regard. CHRIS: I feel like there's such a subtle art to structuring a free trial and particularly the thing you're describing of the way they pace it out. And like, we don't really count it if you're not using it, which makes a lot of sense. There have been so many free trials that I've tried in my life. But like, I started the free trial, and then I forgot about you for a few days. And then I didn't integrate or use. If we're being honest, my free trial has expired, and I have no idea if I want to use you as a service. And I know many platforms will offer to restart your trial or things like that or extend it, or the metered trial days that Knapsack has is an interesting one that I don't think I've heard of before, but I like it as an approach. And I think, frankly, it serves them. They want to give people an actual opportunity to try out the platform and decide if it works for them, and that takes a day or two, it turns out. STEPH: Yeah, I agree. Some of the additional information that they've shown us, as I've been talking about, like the niceties that they've included around the build metrics. They also show you your longest-running test files. So they also have an auto-splitting feature that we haven't tweaked correctly just yet, so I'm waiting to see that happen. But even then, just knowing the build metrics, because again, this is information that Joël and I were working on manually to collect from all the stats that we could from RSpec and using parallel_tests. But now we can just go to the build metrics, and we can see like, oh, these are our top files that take the longest, and then Knapsack Pro tells us your ideal test time for a file is like this number. So to give a concrete number for us, it'd be like around 6 minutes, and 20 seconds would be our ideal time that each node runs. Now, that's probably going to require splitting some of those files because we have a couple of files that take more like eight, nine minutes. But it's so nice to be able to see that and not have to run scripts that we have crafted together to then be able to identify our slowest test. But once we get cue mode working and then also the automatic splitting of files, I'll be sure to keep you updated because I'm hoping we're going to see some sparkly stats in terms of then how the tests are getting distributed and that we'll be able to bring the CI time down at least for this portion; it won't be for the whole build but for running the RSpec suite. If we can match that ideal time that we've seen and that Knapsack Pro says that if we balance everything in split files, then the ideal run time is around six or seven minutes. So here's hoping. But that's really what's going on in my world. What's going on in your world? CHRIS: My world is, I would say, largely the same as it has been. We've been sort of between large projects for a bit now. We've been taking that time to build out some infrastructure, get some smaller things done, some niceties, enhancement, tweaks, et cetera. But at this point, I would say the storm's brewing. The larger projects that we are planning for, mostly Q3 sort of thing, are all kind of coming to a head right now. And so I'm kind of excited. I'm ready. I'm ready for a bigger challenge, something to sink our teeth into and really dive into. So yeah, it's been, I would say, very calm of late in a very positive way but almost maybe too calm. And so I'm ready for, yeah, for different things to try out and some stuff to really dig into and grow the Sagewell platform. But yeah, that's most of what's up in my world. MIDROLL AD: Debugging errors can be a developer’s worst nightmare...but it doesn’t have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help you cut your debugging time in half. So why do developers love Airbrake? Well, it has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake’s debugging tool catches all your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake’s lightweight APM enables developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps and includes modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. So head on over to airbrake.io/try/bikeshed to create your FREE developer account today! STEPH: Well, that's kind of a perfect topic or a jumping-off point for a question that we received recently from a listener that's very focused around when you have a lot of work. And since you've got a lot of work, it sounds like, coming down the pipeline, then how to manage a lot of small projects, and then keep the team in sync with each other. So let me back up and read their question so that way we don't miss any of the good bits. But this question comes from Brian, and Brian writes in, "I've got a listener question for y'all. How do you like to or have seen teams keep the vision of the product clear yet connected to the backlog such that tasks don't feel like a disconnected set of work, especially when the team stream count grows? To expand on my question, the common situation I've seen is when a team has multiple work streams in flight, so using like a backlog tool like Jira or Trello shows a stream of work, but it's hard to associate the stories and tasks either to the bigger picture of the goals or the system's end state. That has slowed down new teammates' onboarding. It's made identifying necessary but missing stories harder earlier on. It's also made reviewing work require more context switching or made it harder for interested parties to track progress. It's also caused tension on teams when individuals have different ideas of the goals and the end state of the work. I can see some obvious options to help but curious what your general and specific experiences and advice might be." All right, so speaking of lots of work coming down the pipeline and managing some small projects, Chris, do you have any initial thoughts around lots of big questions here in terms of keeping the backlog connected to the product vision? CHRIS: Yeah, I have a bunch of little thoughts that I'm happy to share. But to sort of go bigger picture on this, I think the question that Brian is asking here is one of the hard questions of the work that we do. It's like, how do we keep everybody in sync and understanding the big picture while working on the small individual pieces? Like, that's the hard stuff. That's the place where communication problems can happen or where the larger team you have, you start to feel those growing pains, et cetera. So to name it, this is just a hard thing. This is one of those hard things that I don't have any silver bullet by any means. But I do have a couple of things that have worked for me in the past. So the first is having some notion within whatever tool that you're working on of the bigger picture of the projects. And so recently, just to use Sagewell as an example, we started on Trello. And when we were using Trello, we had a projects list off to the side. So there's the actual backlog of next-up work. But next to it, we had a projects list that was a little higher level zoomed out, trying to group things into sections. Pretty quickly, even with our small team, that became insufficient to actually track these things and try and tie small pieces of work back to the bigger project that they were associated with. So we introduced something called I'm going to say it's Hello Epics is the name of the extension for Trello. But it's very much a grafting on of functionality. It's like a Chrome extension; I want to say that takes advantage of card linking and Trello and tries to make some version of this happen. It was okay, but we, again, sort of hit the ceiling of that. We somewhat recently, I'm going to say, a couple of months ago, moved to Linear, and Linear has a more formal idea of projects within certain functional areas. And there are ways that projects sort of span different teams, and individual tasks can associate back to projects. And I would say, for us, it's been just the right amount of structure. I want to have that continuity and the linking between things. But I don't need it to be too fancy. There is a Gantt chart view in Linear, and I look at it, and I'm like, wow, those are dates. You made some guesses there, Linear. Good luck, we'll see if it happens; I don't know. But overall, that functionality has been great and sufficient for where we're at. So that's one thing. Another thing that comes to mind is trying to keep those scoped. So those projects that I'm talking about this is one of the things that I push on a lot is I want that list to be turning over semi-regularly. So we shouldn't have projects that are just like for the next two years, we're building the admin UI, and that's just this sort of open-ended amorphous, unclear project. I like to really push for let's get to some deliverable, some doable line, some perhaps arbitrary MVP definition that we define. But let's make it so that each of these projects is doable such that if something stays in that list for too long, our attention is drawn to that. We don't just become numb to the idea that I don't know, there's a list of projects, but some of them are kind of dead in the water, kind of just hanging around and not quite complete. I want that to be a mechanism for reviewing the work that we have in process. And so often, it almost feels somewhat artificial, but we'll break a bigger body of work down into smaller projects. And so there's like V1 of a thing, and then there's V1.2. And we get somewhat cheeky with the names at times. But I found a lot of value in having that sort of idea of let's define a boundary around a portion of this work, give it a name, and decide are we done with that or not? And each week, we get asked that question, particularly around our product planning meeting. And that has been really useful, particularly to make sure that stuff has a broader context that it's connected to. The last thing that I'll say that has been super useful is retro because what you're describing, again, is one of the harder things. This is really difficult to get right. It's going to be different in each team at different team sizes, at different complexities of product and platform that you're building. You're going to feel this in different ways. And so retro, by far, is the most effective tool I know of to ensure that you are naming and responding to the pain points that you have in your own workflows. There's no one size fits all for this sort of thing. But if you have a process that regularly has you come up for air, take a look at what you're doing and decide is this going well or is this not well? Are we missing critical features? Are developers lacking context? Is it hard to move people between teams or whatever the pain point may be? Then you can try and focus in and actually find solutions specific to that. But again, I can't answer it for you. All I can say is like, by far, retro is the most effective thing I've ever seen for trying to answer that question. So yeah, a couple of thoughts. I don't know. What do you think, Steph? STEPH: I think this is one of those rare moments that you hear someone in a leadership position express that they want high turnover; that is something that they're shooting for. CHRIS: Turnover projects, not people. I like people. STEPH: [laughs] I know. CHRIS: People are moral. People are great. As you said it, I was like, wait, what did I say? Oh, right. No, I didn't. Okay, I got it now. STEPH: [laughs] I left out that important word, high turnover of projects and tickets, yes. [laughs] It amused me as I was thinking about it as you mentioned that it's nice to have that consistent turnover in terms of like, you know that something may have gotten scoped too largely if it's sitting there for a while. Unsurprisingly, all the things that you said are wonderful. I love that you sprinkled retro in there at the end since, as you mentioned, this is hard, and it's going to be hard to get it right. So keep checking in with your team to see where improvements can be made. I'm going to share a recommendation that actually starts with a pain point and then kind of walk it through from there. So one of the areas that Brian highlighted about that is that it makes it harder for interested parties to track progress. I really liked that one because I've also felt that pain. One way that I've experienced teams manage it that I wasn't a fan of is where people would just go to developers where they saw someone's name on a ticket, and they would ask for updates. And the reason I didn't care for that is because it just felt too isolated. And then it felt like work where someone then had to identify who's working on this and getting an update. And then it felt almost stressful to then have someone checking in with you in that regard to be like, hey, how's this ticket going? And then what's the update on this? Versus having a more formal process of like, this is how we update our work. So that sort of like one-off behavior of where then someone who's interested in this has to go find the person that's working on it and then check in with them, I think wasn't great for that person. And then it's also not great for the developer who then needs to switch context and provide a high-level overview of when they think something might be done or how it's going. Because then they need to translate from their developer-focus to then more product-focused. A slight improvement on that process was at least to keep it public. So then, if there was someone that was in more of like a sales role or a customer support role, and then they were curious about something, is at least don't make that a private conversation. So instead of messaging that developer directly, at least put it in a channel where then anybody could respond, which is then nice because then other people can see that someone is checking in on this; they're interested in it. If that person's out, maybe someone else can respond on their behalf, but at least at a minimum, keep it public. Even better is if you can have just a point person, so this is probably your product manager who then someone that's in sales or customer service can go to and say, "Hey, I'd love an update." And then maybe that product manager turns around and goes to the developer and asks questions, but at least they know who to go to, and so they don't have to find the person to follow up with. Another approach that I'm currently experiencing with my team is we do have a number of small projects that are going on within the same team. So there is an important Ruby and Rails upgrade that's going on. There's the normal day-to-day work that needs to get done. And then there's also the CI performance improvement that Joël and I are working on. And this goes back to your point in terms of use all the tools that can then help you promote the work that's getting done. So in our case, we've actually built on you can see in one board, but then you can have subsets, or you can have streams inside those boards. So then you can have a board that is titled...board is kind of a fancy term. It's more like a line item on one larger board for a team to use some weird terminology. [laughs] But I can't think of a more correct term for it. So there's a line item that focuses on Rails and Ruby upgrade. And then there's a line that focuses on other work that's being done, and then that's RSpec-specific performance improvements. And that has felt very nice because then you section each thing together, and you can focus on one at a time. It does expand the context that you have with the work that's going on with that team. And I do have mixed feelings about it because, on one hand, it does make your daily sync longer because then there are people sharing updates or looking for help on things that you frankly don't have a lot of context and that you're not working on. So it can feel a little wasteful to then sit there while they're going through updates for work that you're not part of. But then it's also been really nice because then you get that high-level context. So you don't really have to know the details, but you're at least aware of that work that's being done. So then that way, if a question does come up, you have enough context that you can say, "Oh, I know a little bit about that," or "I know who's working on it," or "I know who to follow up with." So I think the time trade-off is worth it. Even if it may feel a little painful some days, I think it's still really nice. And then also, if you can look for opportunities to form sub-teams where if there's a group and there's work that you can group together. So maybe if you look at the type of work that's coming downstream, like, if you are working on one portion of the application and you see that another big feature is working on that similar area, then maybe grouping that stuff together to reduce some of the context switching is really nice. The buddy system also works really well, and maybe that's pairing, maybe it's not, but it's at least having two people that are working on a larger project. So using that RSpec CI performance improvement as an example, Joël and I both have a lot of context on this. And so that way, one, we always have a buddy, someone to reach out to and talk to. But then for like the CRs or PRs that I'm pushing up, then I usually will tag Joël on those because I know he already has the context. So I'm trying not to bring other people in unless they just want to, but that way, Joël's there, and it makes for a quicker review. So that's one nice benefit of the buddy system is because there's at least one person that has enough context where it's not as big of a hurdle for them. And they don't have to ask as many questions and then get caught up to speed before reviewing your changes. There's another area that Brian identified as struggling to identify important work but missing stories. I'm intrigued by that one because I'm trying to think of where a team is working on a project, but because you've got so many small projects, you may have forgotten about a particular task that needs to get done, or maybe you need to collaborate with another team, and that's something that slipped through the cracks. I don't think I have a great solution for that one, except with time and experience, you'll start to identify some of those areas where have we thought through, like the different teams and communications and the different services that we may need to integrate with? And then I also think it's fine, like, if you've got someone working on a project, it shouldn't be so thoroughly scoped upfront that there's not room for discovery. So if you have one or two people on that project and they're like, hey, actually, I need to create a ticket for this, I think that feels totally reasonable that that's part of that discovery process. CHRIS: Yeah, I think I share that take, or I guess a different way to say it is I don't feel the pain of stuff falling through. But that's because we have kind of a continuous process of as we're working on things, we're like, oh, didn't think of X. And then it's very much a part of our process to throw a ticket into the inbox. And our product manager will then triage that and decide relatively where it goes. But everyone is empowered to do that, everyone that's working on the product, such that we have no expectation of being able to fully scope things out in advance. And thus the idea of missing a ticket...if it gets to a user and like we forgot to build a critical feature, then, well, that would be sad, but that tends to not happen because just the nature of the process is we're in there. And the idea of the fog of war, like, you can't know until you know. You got to go out there in the forest, and then the fog starts to clear. And then you can see, oh, there's a goldmine there. I'm going to stop with my analogy now. But more generally, this is just sort of agile in my mind. I'm a big fan of limiting the specificity the further out a project plan is. So right now, we're working on the concrete implementation of a thing. Cool, that's real. Let's have detailed tickets that describe as much as necessary to actually do the work. And then like a little further out the projects, let's talk about the feature level. What's the screen that we want to build but not necessarily all of the nitty-gritty details? And then, further than that, the roadmap, I want to get away from either implementation or feature level and go to benefits. What's the user going to be able to do as a result of this? And user can be a little bit abstract where your customers are developers right now on the team. You're trying to empower them. So it's like CI needs to be faster. And so that's the benefit that we're trying to get to. And then the features are what we want to do — splitting into queues, and then the actual implementation is integrate Knapsack Pro and whatnot. And the closer the work is to actually being something that you're tackling, the more specificity I think is useful. But very purposefully, I will avoid specificity for things that are more than a month or two out just to be like, can those just be bullet items on a list that kind of talk about how happy a user will be when we do it but not actually constrain ourselves to a particular feature or implementation? Because we're going to figure some stuff out and it's going to change. And also, it's so much easier, like the idea of the team not being able to picture all of the different moving pieces of work. If your roadmap is simple in a couple of bullet items, then it's much easier for everyone to be like, yeah, I kind of know all the stuff that we're going to be doing, that we think we'll be doing in six months. Could change turns out, but that's a thing that I'm a big fan of is limiting the specificity further out. And I've worked on many projects where like, no, no, we absolutely need to know down to the day how long this roadmap will take that we think is about a year. And it's like, that's not real. That's not a real thing. Stuff's going to change. I assure you. STEPH: I love that. The further out that you get, you focus more on benefits versus implementation. I think that hits home for so many reasons and helps address a number of the concerns that Brian brought up. I did think of one more strategy that I've seen that I've also enjoyed is where if you do have an interested party who is like, hey, I've got, I don't know, maybe you've got a customer that's really mad about something, and there's a bug fix. And so this person in customer support really wants to be able to know exactly how this bug is going. Invite them to your daily sync. Let them attend, and they can come, and they'll know who's working on it. They can get a daily update as to how things are going. I think that's a really nice addition. There's also the idea that if you are collaborating closely with another team and so your work is very important to theirs or vice versa, also have one person from their team join your daily sync or vice versa. But then that way, you have that communication. And that way, you can check in with each other, and you're at least aware of that high-level context in terms of like, oh, we're waiting on this team for designs or for a new server or something, things like that. Then they can provide an update, or you can provide an update to them. CHRIS: I probably shouldn't be surprised, but we had a surprising amount to say about that question. [laughs] It's really in our wheelhouse, the sort of stuff that we like to dig into. How do we do the work? You know, that's the question here on The Bike Shed. But I think with all of those notes, Brian, I hope that helps with what you're doing. And yeah, what do you think, Steph? Should we wrap up? STEPH: Let's wrap up. CHRIS: 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 hosts@bikeshed.fm via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeee!!!!!!!! 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:Airbrake: Deploy fearlessly and fix bugs faster with Airbrake Error & Performance Monitoring. Airbrake notifiers are available for all major programming languages and frameworks, and install in minutes, with an open-source SDK-based install and near-zero technical debt. Spend less time tracking down bugs and more time developing. Visit Frictionless error monitoring and performance insight for your app stack.Support The Bike Shed
undefined
Jul 26, 2022 • 39min

347: Tracking Velocity

Chris talks about a small toy app he maintains on the side and working with a project called capybara_table. Steph is getting ready for maternity leave and wonders how you track velocity and know if you're working quickly enough? They answer a listener's question about where to get started testing a legacy app. This episode is brought to you by Airbrake. Visit Frictionless error monitoring and performance insight for your app stack. jnicklas/capybara_table: Capybara selectors and matchers for working with HTML tables Become a Sponsor of The Bike Shed! Transcript: CHRIS: Just gotta hold on. Fly this thing straight to the crash site. STEPH: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Chris Toomey. CHRIS: And I'm Steph Viccari. STEPH: And together, we're here to share a bit of what we've learned along the way. I love that you rolled with that. [laughs] CHRIS: No, actually, it was the only thing I could do. I [laughs] was frozen into action is a weird way to describe it, but there we are. STEPH: I mentioned to you a while back that I've always wanted to do that. Today was the day. It happened. CHRIS: Today was the day. It wasn't even that long ago that you told me. I feel like you could have waited another week or two. I feel like maybe I was too prepared. But yeah, for anyone listening, you may be surprised to find out that I am not, in fact, Steph Viccari. STEPH: And they'll be surprised to find out that I actually am Chris Toomey. This is just a solo monologue. And you've done a great job of two voices [laughs] this whole time and been tricking everybody. CHRIS: It has been a struggle. But I'm glad to now get the proper recognition for the fact that I have actually [laughs] been both sides of this thing the whole time. STEPH: It's been a very impressive talent in how you've run both sides of the conversation. Well, on that note, [laughs] switching gears just a bit, what's new in your world? CHRIS: What's new in my world? Answering now as Chris Toomey. Let's see; I got two small updates, one a very positive update, one a less positive update. As is the correct order, I'm going to lead with the less positive thing. So I have a small toy app that I maintain on the side. I used to have a bunch of these little purpose-built singular apps, typically Rails app sort of things where I would play with a new technology, but it was some sort of like, oh, it's a tracker. It's a counter. We talked about breakable toys in the past. These were those, for me, serve different purposes, productivity things, or whatever. But at some point, I was like, this is too much work, so I consolidated them all. And I kept like, there was a handful of features that I liked, smashed them all together into one Rails app that I maintain. And that's just like my Rails app. It turns out it's useful to be able to program the internet. So I was like, cool, I'll do that for myself. I have this little app that I maintain. It's got like a journal in it and other things. I think I've talked about the journal in the past. But I don't actually take that good care of it. I haven't added any features in a while. It mostly just does what it's supposed to, but it had...entropy had gotten the better of it. And so, I had a very small feature that I wanted to add. It was actually just a Rake task that should run in the background on a schedule. And if something is out of order, then it should send me an email. Basically, just an update of like, you need to do something. It seemed like such a simple task. And then, oh goodness, the failure modes that I fell into. First, I was on Heroku-18. Heroku is currently on their Heroku-22 stack. 18 being the year, so it was like 2018, and then there's a 2020 stack, and then the 2022. That's the current one. So I was two stacks behind, and they were yelling at me about that. So I was like, okay, but whatever. Can I ignore that for a little while? Turns out no, because I couldn't even get the app to boot locally, something about some gems or some I think Webpacker was broken locally. So I was trying to fix things, finally got that to work. But then I couldn't get it to build on CircleCI because Node needed Python, Python 2 specifically, not Python 3, in order to build Node dependencies, particularly LibSass, I want to say, or node-sass. So node-sass needed Python 2, which I believe is end of life-d, to build a CSS authoring tool. And I kind of took a step back at that moment, and I was like, what did we do, everybody? What is going on here? And thankfully, I feel like there was more sort of unification of tools and simplification of the build tool space and whatnot. But I patched it, and I fixed some things, then finally I got it working. But then Memcache wasn't working, and I had to de-provision that and reprovision something. The amount of little...like, each thing that I fixed broke something else. I was like, the only thing I can do at this point is just burn the entire app down and rebuild it. Thankfully, I found a working version of things. But I think at some point, I've got to roll up my sleeves some weekend and do the full Rails, Ruby, everything upgrade, just get back to fresh. But my goodness, it was rough. STEPH: I feel like this is one of those reasons where we've talked in the past about you want to do something, and you keep putting it off. And it's like, if I had just sat down and done it, I could have knocked it out. Like, oh, it only took me like 5-10 minutes. But then there's this where you get excited, and then you want to dive in. And then suddenly, you do spend an hour or however long, and you're just focused on trying to get to the point where you can break ground and start building. I think that's the resistance that we're often fighting when we think about, oh, I'm going to keep delaying this because I don't know how long it's going to take. CHRIS: There's something that I see in certain programming communities, which is sort of a beginner-friendliness or a beginner's mindset or a welcomingness to beginners. I see it, particularly in the Svelte world, where they have a strong focus on being able to pick something up and run with it immediately. The entire tutorial is built as there's the tutorial on the one side, like the text, and then on the right side is an interactive REPL. And you're just playing with the Svelte REPL and poking around. And it's so tangible and immediate. And they're working on a similar thing now for SvelteKit, which is the meta-framework that does server-side rendering and all the fancy stuff. But I love the idea that that is so core to how the Svelte community works. And I'll be honest that other times, I've looked at it, and I've been like, I don't care as much about the first run experience; I care much more about the long-term maintainability of something. But it turns out that I think those two are more coupled than I had initially...like, how easy is it for a beginner to get started is closely related to or is, you know, the flip side of how easy is it for me to maintain that over time, to find the documentation, to not have a weird builder that no one else has ever seen. There's that wonderful XKCD where it's like, what's the saddest thing on the internet? Seeing the question that you have asked by one other person on Stack Overflow and no answers four years ago. It's like, yeah, that's painful. You actually want to be part of the boring, mundane, everybody's getting the same errors, and we have solutions to them. So I really appreciate when frameworks and communities care a lot about both that first run experience but also the maintainability, the error messages, the how okay is it for this system to segfault? Because it turns out segfaults prints some funny characters to your terminal. And so, like the range from human-friendly error message all the way through to binary character dump, I'm interested in folks that care about that space. But yeah, so that's just a bit of griping. I got through it. I made things work. I appreciate, again, the efforts that people are putting in to make that sad situation that I experienced not as common. But to highlight something that's really great and wonderful that I've been working with, there is a project called capybara_table. capybara_table is the gem name. And it is just this delightful little set of matchers that you can use within a Capybara, particularly within feature spec. So if you have a table, you can now make an assertion that's like, expect the table to have table row. And then you can basically pass it a hash of the column name and the value, but you can pass it any of the columns that you want. And you can pass it...basically, it reads exactly like the user would read it. And then, if there's an error, if it actually doesn't find it, if it misses the assertion, it will actually print out a little ASCII table for you, which is so nice. It's like, here's the table row that I saw. It didn't have what you were looking for, friend, sorry about that. And it's just so expressive. It forces accessibility because it basically looks at the semantic structure of a table. And if your table is not properly semantically structured, if you're not using TDs and TRs, and all that kind of stuff, then it will not find it. And so it's another one of those cases where testing can be a really useful constraint from the usability and accessibility of your application. And so, just in every way, I found this project works so well. Error messages are great. It forces you into a better way of building applications. It is just a wonderful little tool that I found. STEPH: That's awesome. I've definitely seen other thoughtboters when working in codebases that then they'll add really nice helper methods around that for like checking does this data exist in the table? And so I'm used to seeing that type of approach or taking that type of approach myself. But the ASCII table printout is lovely. That's so...yeah, that's just a nice cherry on top. I will have to lock that one away and use that in the future. CHRIS: Yeah, really, just such a delightful thing. And again, in contrast to the troubles of my weekend, it was very nice to have this one tool that was just like, oh, here's an error, and it's so easy to follow, and yeah. So it's good that there are good things in the world. But speaking of good things, what's new in your world? I hope good things. And I hope you're not about to be like, everything's terrible. But what's up with you? [laughter] STEPH: Everything's on fire. No, I do have some good things. So the good thing is that I'm preparing for...I have maternity leave that's coming up. So I am going to take maternity leave in about four-ish weeks. I know the date, but I'm saying the ish because I don't know when people are listening. [laughs] So I'm taking maternity leave coming up soon. I'm very excited, a little panicked mostly about baby preparedness, because, oh my goodness, it is such an overwhelming world, and what everyone thinks you should or shouldn't have and things that you need to do. So I've been ramping up heavily in that area. And then also planning for when I'm gone and then what that's going to look like for the team, and for clients, and for making sure I've got work wrapped up nicely. So that's a big project. It's just something that's on my mind, something that I am working through and making plans for. On the weird side, I ran into something because I'm still in test migration world. That is one of like, this is my mountain. This is my Everest. I am determined to get all of these tests. Thank you to everyone who has listened to me, especially you, listen to me talk about this test migration path I've been on and the journey that it's been. This is the goal that I have in mind that I really want to get done. CHRIS: I know that when you said, "Especially you," you were talking to me, Chris Toomey. But I want to imagine that every listener out there is just like, aww, you're welcome, Steph. So I'm going to pretend for my own sake that that's what you meant by, especially you. It's especially every one of you out there in the audience. STEPH: Yes, I love either version. And good point, because you're right, I'm looking at you. So I can say especially you since you've been on this journey with me, but everybody listening has been on this journey with me. So I've got a number of files left that I'm working through. And one of the funky things that I ran into, well, it's really not funky; it was a little bit more of an educational rabbit hole for me because it's something that I hadn't considered. So migrating over a controller test over from Test::Unit to then RSpec, there are a number of controller tests that issue requests or they call the same controller method multiple times. And at first, I didn't think too much about it. I was like, okay, well, I'm just going to move this over to RSpec, and everything is going to be fine. But based on the way a lot of the information is getting set around logging in a user and then performing an action, and then trying to log in a different user, and then perform another action that was causing mayhem. Because then the second user was never getting logged in because the first user wasn't getting logged out. And it was causing enough problems that Joël and I both sat back, and we're like, this should really be a request back because that way, we're going through the full Rails routing. We're going through more of the sessions that get set, and then we can emulate that full request and response cycle. And that was something that I just hadn't, I guess, I hadn't done before. I've never written a controller spec where then I was making multiple calls. And so it took a little while for me to realize, like, oh, yeah, controller specs are really just unit test. And they're not going to emulate, give us the full lifecycle that a request spec does. And it's something that I've always known, but I've never actually felt that pain point to then push me over to like, hey, move this to a request spec. So that was kind of a nice reminder to go through to be like, this is why we have controller specs. You can unit test a specific action; it is just hitting that controller method. And then, if you want to do something that simulates more of a user flow, then go ahead and move over to the request spec land. CHRIS: I don't know what the current status is, but am I remembering correctly that the controller specs aren't really a thing anymore and that you're supposed to just use request specs? And then there's features specs. I feel like I'm conflating...there's like controller requests and feature, but feature maybe doesn't...no, system, that's what I'm thinking of. So request specs, I think, are supposed to be the way that you do controller-like things anymore. And the true controller spec unit level thing doesn't exist anymore. It can still be done but isn't recommended or common. Does that sound true to you, or am I making stuff up? STEPH: No, that sounds true to me. So I think controller specs are something that you can still do and still access. But they are very much at that unit layer focus of a test versus request specs are now more encouraged. Request specs have also been around for a while, but they used to be incredibly slow. I think it was more around Rails 5 that then they received a big increase in performance. And so that's when RSpec and Rails were like, hey, we've improved request specs. They test more of the framework. So if you're going to test these actions, we recommend going for request specs, but controller specs are still there. I think for smaller things that you may want to test, like perhaps you want to test that an endpoint returns a particular status that shows that you're not authorized or forbidden, something that's very specific, I think I would still reach for a controller spec in that case. CHRIS: I feel like I have that slight inclination to the unit spec level thing. But I've been caught enough by different things. Like, there was a case where CSRF wasn't working. Like, we made some switch in the application, and suddenly CSRF was broken, and I was like, well, that's bad. And the request spec would have caught it, but the controller spec wouldn't. And there's lots of the middleware stack and all of the before actions. There is so much hidden complexity in there that I think I'm increasingly of the opinion, although I was definitely resistant to it at first, but like, yeah, maybe just go the request spec route and just like, sure. And they'll be a little more costly, but I think it's worth that trade-off because it's the stuff that you're not thinking about that is probably the stuff that you're going to break. It's not the stuff that you're like, definitely, if true, then do that. Like, that's the easier stuff to get right. But it's the sneaky stuff that you want your tests to tell you when you did something wrong. And that's where they're going to sneak in. STEPH: I agree. And yeah, by going with the request specs, then you're really leaning into more of an integration test since you are testing more of that request/response lifecycle, and you're not as likely to get caught up on the sneaky stuff that you mentioned. So yeah, overall, it was just one of those nice reminders of I know I use request specs. I know there's a reason that I favor them. But it was one of those like; this is why we lean into request specs. And here's a really good use case of where something had been finagled to work as a controller test but really rightfully lived in more of an integration request spec. MIDROLL AD: Debugging errors can be a developer’s worst nightmare...but it doesn’t have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help you cut your debugging time in half. So why do developers love Airbrake? Well, it has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake’s debugging tool catches all your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake’s lightweight APM enables developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps and includes modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. So head on over to airbrake.io/try/bikeshed to create your FREE developer account today! STEPH: Changing gears just a bit, I have something that I'd love to chat with you about. It came up while I was having a conversation with another thoughtboter as we were discussing how do you track velocity and know if you're working quickly enough? So since we often change projects about every six months, there's the question of how do I adapt to this team? Or maybe I'm still newish to thoughtbot or to a team; how do I know that I am producing the amount of work that the client or the team expects of me and then also still balancing that and making sure that I'm working at a sustainable pace? And I think that's such a wonderful, thoughtful question. And I have some initial thoughts around it as to how someone could track velocity. I also think there are two layers to this; there could be are we looking to track an individual's velocity, or are we looking to track team velocity? I think there are a couple of different ways to look at this question. But I'm curious, what are your thoughts around tracking velocity? CHRIS: Ooh, interesting. I have never found a formal method that worked in this space, no metric, no analysis, no tool, no technique that really could boil this down and tell a truth, a useful truth about, quote, unquote, "Velocity." I think the question of individual velocity is really interesting. There's the case of an individual who joins a team who's mostly working to try and support others on the team, so doing a lot of pairing, doing a lot of other things. And their individual velocity, the actual output of lines of code, let's say, is very low, but they are helping the overall team move faster. And so I think you'll see some of that. There was an episode a while back where we talked about heuristics of a team that's moving reasonably well. And I threw out the like; I don't know, like a pull request a day sort of thing feels like the only arbitrary number that I feel comfortable throwing out there in the world. And ideally, these pull requests are relatively small, individual deployable things. But any other version of it, like, are we thinking lines of code? That doesn't make sense. Is it tickets? Well, it depends on how you size your tickets. And I think it's really hard. And I think it does boil down to it's sort of a feeling. Do we feel like we're moving at a comfortable clip? Do I feel like I'm roughly keeping pace with the rest of the team, especially given seniority and who's been on the team longer? And all of those sorts of things. So I think it's incredibly difficult to ask about an individual. I have, I think, some more pointed thoughts around as a team how we would think about it and communicate about velocity. But I'm interested what came to mind for you when you thought about it, particularly for the individual side or for the team if you want to go in that direction. STEPH: Yeah, most of my initial thoughts were more around the individual because I think that's where this person was coming from because they were more interested in, like, how do I know that I'm producing as much as the team would expect of me? But I think there's also the really interesting element of tracking a team's velocity as well. For the individual, I think it depends a lot on that particular team and their goals and what pace they're moving at. So when I do join a new team, I will look around to see, okay, well, what's the cadence? What's the standard bar for when someone picks up a ticket and then is able to push it through? How much cruft are we working with in the codebase? Because then that will change the team's expectations of yes, we know that we have a lot of legacy code that we're working with, and so it does take us longer to get through things. And that is totally fine because we are looking more to optimize our sustainability and improving the code as we go versus just trying to get new features in. I think there's also an important cultural aspect. So some teams may, unfortunately, work a lot of extra hours. And that's something that I won't bend for. I'm still going to stick to my sustainable hours. But that's something that I keep in mind that just if some other people are working a lot of evenings or just working extra hours to keep that in mind that if they do have a higher velocity to not include that in my calculation as heavily. I also really liked how you highlighted that certain individuals often their velocity is unblocking others. So it's less about the specific code or features or tickets that they're producing, but it's how many people can they help? And then they're increasing the velocity of those individuals. And then the other metrics that unfortunately can be gamified, but it's still something to look at is like, how many hours are you spending on a particular feature, the tickets? But I like that phrasing that you used earlier of what's your progress? So if someone comes to daily sync and they mention that they're working on the same thing and we're on like day three, or four, but they haven't given an update around, like, oh, I have this new thing that I'm focused on, or this new area that I'm exploring, that's when I'll start to have alarm bells go off. And I'm like, okay, you've been working on the same thing. I can't quite tell if you've made progress. It sounds like you're still in the depths of the original thing that you were on a couple of days ago. So at that point, I'm going to want to check in to see how you're doing. But yeah, I think that's why this question fascinates me so much is because I don't think there's one answer that fits for everybody. There's not a way to tell one person to say, "Hey, this is your output that you should be producing, and this applies to all teams." It's really going to vary from team to team as to what that looks like. I remember there was one team that I joined that initially; I panicked because I noticed that their team was moving at a slower rate in terms of the number of tickets and PRs and stuff that were getting pushed up, reviewed, and then merged. That was moving at a slower pace than I was used to with previous clients. And I just thought, oh, what's going on? What's slowing us down? Like, why aren't we moving faster? And I actually realized it's just because they were working at a really sustainable pace. They showed up to the office. This was back in the day when I used to go to an office, and people showed up at like 9:00 a.m. and then 5:00 o'clock; it was a ghost town, and people were gone. So they were doing really solid, great work, but they were sticking to very sustainable hours. Versus, a previous team that I had been on had more of like a rushed feeling, and so there was more output for it. And that was a really nice reset for me to watch this team and see them do such great work in a sustainable fashion and be like, oh, yeah, not everything has to be a fire, not everything has to be rushed. I think the biggest thing that I'd look at is if velocity is being called into question, so if someone is concerned that someone's not producing enough or if the team is not producing enough, the first place I'm going to look is what's our priorities and see are we prioritizing correctly? Or are people getting pulled into a lot of work that's not supporting the priorities, and then that's why suddenly it feels like we're not producing at the level that we need to? I feel like that's the common disconnect between how much work we're getting done versus then what's actually causing people or product managers, or management stress. And so reevaluating to make sure that they're on the same page is where I would look first before then thinking, oh, someone's not working hard enough. CHRIS: Yeah, I definitely resonate with all of that. That was a mini masterclass that you just gave right there in all of those different facets. The one other thing that comes to mind for me is the question is often about velocity or speed or how fast can we go. But I increasingly am of the opinion that it's less about the actual speed. So it's less about like, if you think about it in terms of the average pace, the average number of features that we're going through, I'm more interested in the standard deviation. So some days you pick up a ticket, and it takes you a day; some days you pick up a ticket, and suddenly, seven days later, you're still working on it. And both at the individual level and at the team level, I'm really interested in decreasing that standard deviation and making it so that we are more consistently delivering whatever amount of output it is but very consistently doing that. And that really helps with our ability to estimate overall bodies of work with our ability for others to know and for us to be able to sort of uphold expectations. Versus if randomly someone might pick up a piece of code or might pick up a ticket that happens to hit a landmine in the code, it's like, yeah, we've been meaning to refactor that for a while. And it turns out that thing that you thought would be super easy is really hard because we've been kicking the can on this refactoring of the fundamental data model. Sorry about that. But today's your day; you lose. Those are the sort of things that I see can be really problematic. And then similarly, on an individual side, maybe there's some stuff that you can work on that is super easy for you. But then there's other stuff that you kind of hit a wall. And I think the dangerous mode to get into is just going internal and not really communicating about that, and struggling and trying to get there on your own rather than asking for help. And it can be very difficult to ask for help in those sorts of situations. But ideally, if you're focusing on I want to be delivering in that same pace, you probably might need some help in that situation. And I think having a team that really...what you're talking about of like, if I notice someone saying the same thing at daily sync for a couple of days in a row, I will typically reach out in a very friendly, collegial way, hey, do you want someone else to take a look at that with you? Because ideally, we want to unblock those situations. And then if we do have a team that is pretty consistently delivering whatever overall velocity but it's very consistent at that velocity, it's not like 3 one day and then 0, and then 12, and then 2; it's more of like, 6,5,6,5 sort of thing, to pick random numbers out of the air, then I feel so much more able to grow that, to increase that. If the question comes to me of like, hey, we're looking at the budget for the next quarter; do we think we want to hire another developer? I think I can answer that much more accurately at that point and say what do I think that additional individual would be able to do on the team. Versus if development is kind of this sporadic thing all over the place, then it's so much harder to understand what someone new joining that team would be able to do. So it's really the slow is smooth, smooth is fast adage that I've talked about in the past that really captured my mind a while back that just continues to feel true to me. And then yeah, I can work with that so much better than occasional days of wild productivity and then weeks of sadness in the swamp of refactoring. So it's a different way to think about the question, but it is where my mind initially went when I read this question. STEPH: I'm going to start using that description for when I'm refactoring. I'm in the refactoring swamp. That's where I'm spending my time. [laughs] Talking about this particular question is helping me realize that I do think less in terms of like what is my output in the strict terms of tickets, and PRs, and things like that. But I do think more about my progress and how can I constantly show progress, not just to the world but show it to myself. So if there are tickets that then maybe the ticket was scoped too big at first and I've definitely made some really solid progress, maybe I'm able to ship something or at least identified some other work that could be broken out, then I'm going to do that. Because then I want everybody to know, like, hey, this is the progress that was made here. And I may even be able to make myself feel good and move something over to the done column. So there's that aspect of the work that I focus on more heavily. And I feel like that also gives us more opportunities to then iterate on what's the goal? Like, we're not looking to just churn out work. That's not the point. But we really want to focus on meaningful work to get done. So if we're constantly giving an update on this as the progress that I've made in this direction, that gives people more opportunities to then respond to that progress and say, "Oh, actually, I think the work was supposed to do this," or "I have questions about some of the things that you've uncovered." So it's less about just getting something done. But it's still about making sure that we're working on the right thing. CHRIS: Yeah, it doesn't matter how fast we're going if we're going in the wrong direction, so another critical aspect. You can be that person on the team who actually doesn't ship much code at all. Just make sure that we don't ship the wrong code, and you will be a critical member of that team. But shifting gears just a little bit, we have another listener question here that I'd love to get into. This one is about testing a legacy app. So reading this question, it starts off with a very nice note to us, Steph. "I want to start by saying thanks for putting out great content week after week." We are very happy to do so." So a question for you two. I just took over a legacy Rails app. It's about 12 years old, and it's a bit of a mess. There was some testing in place, but it was completely broken and hadn't been touched in over seven years. So I decided to just delete it all. My question is, where do I even start with testing? There are so many callbacks on the models and so many controller hooks that I feel like I somehow need to have a factory for every model in our repo. I need to get testing in place ASAP because that is how I develop. But we are also still on Ruby 2 and Rails 4.0. So we desperately have to upgrade. Thanks in advance for any advice." So Steph, I actually replied in an email to this kind listener who sent this. And so, I definitely have some thoughts, but I'm interested in where would you start with this. STEPH: Legacy code, I wouldn't know anything about working in legacy code. [laughs] This is a fabulous question. And yeah, the response that you provided is incredible. So I'm very excited for you to share the message that you replied with. So I'm going to try not to steal any of those because they're wonderful. But to add to that list that is soon to come, often where I start with applications like these where I need some testing in place because, as this person mentioned, that's how they work. And then also, at that point, you're just scared to ship anything because you just don't know what's going to break. So one area that you could start with is what's your rollback strategy? So if you don't have any tests in place and you send something out into the world, then what's your plan to then be able to either roll back to a safe point or perhaps it's using feature flags for anything new that you're adding so that way you can quickly turn something on and off. But having a strategy there, I think, will help alleviate some of that stress of I need to immediately add tests. It's like, yes, that's wonderful, but that's going to take time. So until you can actually write those tests, then let's figure out a plan to mitigate some of that pain. So that's where I would initially start. And then, as for adding the test, typically, you start with testing as you go. So I would add tests for the code that I'm adding that I'm working on because that's where I'm going to have the most context. And I'm going to start very high. So I might have really slow tests that test everything that is going to be feature level, integration level specs because I'm at the point that I'm just trying to document the most crucial user flows. And then once I have some of those in place, then even if they are slow, at least I'm like, okay, I know that the most crucial user flows are protected and are still working with this change that I'm making. And in a recent episode, we were talking about how to get to know a Rails app. You highlighted a really good way to get to know those crucial user flows or the most common user flows by using something like New Relic and then seeing what are the paths that people are using. Maybe there's a product manager or just someone that you're taking the app over that could also give you some help in letting you know what's the most crucial features that users are relying on day to day and then prioritizing writing tests for those particular flows. So then, at this point, you've got a rollback strategy. And then you've also highlighted what are your most crucial user flows, and then you've added some really high level probably slow tests. Something that I've also done in the past and seen others do at thoughtbot when working on a legacy project or just working on a project, it wasn't even legacy, but it just didn't have any test coverage because the team that had built it before hadn't added test coverage. We would often duplicate a lot of the tests as well. So you would have some integration tests that, yes, frankly, were very similar to others, which felt like a bad choice. But there was just some slight variation where a user-provided some different input or clicked on some small different field or something else happened. But we found that it was better to have that duplication in the test coverage with those small variations versus spending too much time in finessing those tests. Because then we could always go back and start to improve those tests as we went. So it really depends. Are you in fire mode, and maybe you need to duplicate some stuff? Or are you in a state where you can be more considerate with your tests, and you don't need to just get something in place right away? Those are some of the initial thoughts I have. I'm very excited for the thoughts that you're about to share. So I'm going to turn it over to you. CHRIS: It's sneaky in this case. You have advanced notice of what I'm about to say. But yeah, this is a super interesting topic and one of those scary places to find yourself in. Very similar to you, the first thing that I recommended was feature specs, starting at that very high level, particularly as the listener wrote in and saying there are a lot of model callbacks and controller callbacks. And before filters and all of this, it's very indirect how this application works. And so, really, it's only when the whole thing is integrated together that you're going to have a reasonable sense of what's going on. And so trying to write those high-level feature specs, having a handful of them that give you some confidence when you're deploying that those core workflows are still working as expected. Beyond that, the other things that I talked about one was observability. As an aside, I didn't mention feature flags or anything like that. And I really loved that that was something you highlighted as a different way to get to confidence, so both feature flags and rollbacks. Testing at the end of the day, the goal is to have confidence that we're deploying software that works, and a different way to get that is feature flags and rollbacks. So I really love that you highlighted that. Something that goes really well hand in hand with those is observability. This has been a thing that I've been exploring more and more and just having some tooling that at runtime will tell you if your application is behaving as expected or is not. So these can be APM-type tools, but it can also be things like Sentry or Honeybadger error monitoring, those sorts of things. And in a system like this, I wouldn't be surprised if maybe there was an existing error monitoring tool, but it had just kind of decayed over time and now just has perhaps thousands of different entries in it that have been ignored and whatnot. On more than one occasion, I've declared Sentry bankruptcy working with clients and just saying like, listen; this thing can't tell us any truths anymore. So let's burn it down and restart it. So I would recommend that and having that as a tool such that much as tests are really wonderful before the code gets out there into the wild; it turns out it's only when users start using it that the real stuff happens. And so, having observability, having tooling in place that will tell you when something breaks is equally critical in my mind. One of the other things I said, and this is probably the spiciest take on my list, is questioning the trade-off space that you're in. Is this an application that actually has a relatively low defect rate that users use and are quite happy with, and expect that level of performance and correctness, and all of those sorts of things, and so you, frankly, need to be careful with it? Or, is it potentially something that has a handful of bugs and that users are used to a certain lower fidelity experience, let's call it? And can you take advantage of that if that happens to be true? Like, I would be very careful to break something that has never been broken before that there's no expectation of that. But if we can get away with moving fast and breaking things for a little while just to try and get ourselves out of the spot that we're in, I would at least want to consider that trade-off space. Because caution slows you down, it means that your progress is going to be limited. And so, if we're able to reduce the caution filter just a little bit and move a little bit more rapidly, then ideally, we can get out of this place that we're in a little more quickly. Again, I think that's a really subtle one and one that you'd have to get buy-in from product managers and probably be very explicit in the conversations and sort of that trade-off space. But it is something that I would want to explore if I found myself in this sort of situation. The last thing that I highlighted was the fact that the versions of Ruby and Rails that were listed in the question are, I think, both end of life at this point. And so from a security perspective, that is just a giant glaring warning sign in the corner because the day that your app gets hacked, well, that's a bad day. So testing, unfortunately, I think that's the main way that you're going to get by on that as you're going through upgrades. You can deploy a new version of the application and see what happens and see if your observability can get you there. But really, testing is what you want to do. So that's where building out that testing is all the more critical so that you can perform those security upgrades because they are now truly critical to get done. And so it gives sort of more than a nice to have, more than this makes me feel comfortable. It is pretty much a necessity if you want to go through that, and you absolutely need to go through the security upgrades because otherwise, you're going to get hacked. There are just automated scanners out there. They're going to find you. You don't need to be a high vulnerability target to get taken down on the internet these days. So if it hasn't happened yet, it's going to. And I think that's an easy business case to sell is, I guess, the way that I would frame it. So those were some of my thoughts. STEPH: You bring up a really good point about needing to focus on the security upgrades. And I'm thinking that through a little bit further in regards to what trade-offs would I make? Would I wait till I have tests in place to then start the upgrades, or would I start the upgrades now but just know I'm going to spend more time manual testing on staging? Or maybe I'm solo on the project. If I have a product manager or someone else that can also help the testing with me, I think I would go for that latter approach where I would start the upgrades today and then just do more manual testing of those crucial flows and then have that rollback strategy. And as you mentioned, it's a trade-off in terms of, like, how important is it that we don't break anything? CHRIS: I think similar to the thing that both of us hit on early on is like, have some feature specs that just kick the whole application as one connected piece of code. Have that in place for the security upgrade, testing. But I agree, I wouldn't want to hold off on that because I think that's probably the scariest part of all of this. But yeah, it is, again, trade-offs. As always, it depends. But I think those are my thoughts. Anything else you want to add, Steph? STEPH: I think those are fabulous thoughts. I think you covered it all. CHRIS: Sounds good. Well, in that case, should we wrap up? STEPH: Let's wrap up. CHRIS: 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 hosts@bikeshed.fm via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeee!!!!!!!! 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:Airbrake: Deploy fearlessly and fix bugs faster with Airbrake Error & Performance Monitoring. Airbrake notifiers are available for all major programming languages and frameworks, and install in minutes, with an open-source SDK-based install and near-zero technical debt. Spend less time tracking down bugs and more time developing. Visit Frictionless error monitoring and performance insight for your app stack.Support The Bike Shed
undefined
Jul 19, 2022 • 37min

346: Occasional Biscuits

Natural disaster movies, anyone? It's what Steph's been into, and Chris has THOUGHTS on the drilling in Armageddon. Additionally, a chat around RuboCop RSpec rules happens, and they answer a listener's question, "how do you get acquainted with a new code base?" This episode is brought to you by BuildPulse. Start your 14-day free trial of BuildPulse today. Greenland Geostorm San Andreas Armageddon This episode is brought to you by Airbrake. Visit Frictionless error monitoring and performance insight for your app stack. Become a Sponsor of The Bike Shed! Transcript: AD: Flaky tests take the joy out of programming. You push up some code, wait for the tests to run, and the build fails because of a test that has nothing to do with your change. So you click rebuild, and you wait. Again. And you hope you're lucky enough to get a passing build this time. Flaky tests slow everyone down, break your flow, and make things downright miserable. In a perfect world, tests would only break if there's a legitimate problem that would impact production. They'd fail immediately and consistently, not intermittently. But the world's not perfect, and flaky tests will happen, and you don't have time to fix all of them today. So how do you know where to start? BuildPulse automatically detects and tracks your team's flaky tests. Better still, it pinpoints the ones that are disrupting your team the most. With this list of top offenders, you'll know exactly where to focus your effort for maximum impact on making your builds more stable. In fact, the team at Codecademy was able to identify their flakiest tests with BuildPulse in just a few days. By focusing on those tests first, they reduced their flaky builds by more than 68% in less than a month! And you can do the same because BuildPulse integrates with the tools you're already using. It supports all of the major CI systems, including CircleCI, GitHub Actions, Jenkins, and others. And it analyzes test results for all popular test frameworks and programming languages, like RSpec, Jest, Go, pytest, PHPUnit, and more. So stop letting flaky tests slow you down. Start your 14-day free trial of BuildPulse today. To learn more, visit buildpulse.io/bikeshed. That's buildpulse.io/bikeshed. CHRIS: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Chris Toomey. STEPH: And I'm Steph Viccari. CHRIS: And together, we're here to share a bit of what we've learned along the way. So, Steph, what's new in your world? STEPH: Hey, Chris. So I've been watching more movies lately. So evenings aren't always great; I don't always feel good being around 33 weeks pregnant now. Evenings I can be just kind of exhausted from the day, and I just need to chill and prop my feet up and all that good stuff. And I've been really drawn to natural disaster like end-of-the-world-type movies, and I'm not sure what that says about me. But it's my truth; it's where I'm at. [chuckles] I watched Greenland recently, which I really enjoyed. I feel like they ended it well. I won't share any spoilers, but I feel like they ended it well. And they didn't take an easy shortcut out that I kind of thought that they might do, so that one was enjoyable. Geostorm, I watched that one just last night. San Andreas, I feel like that's one that I also watched recently. So yeah, that's what's new in my world, you know, your typical natural disaster end-of-the-world flicks. That's my new evening hobby. CHRIS: I feel like I haven't heard of any of the three that you just listed, which is wild to me because this is a category that I find enthralling. STEPH: Well, definitely start with Greenland. I feel like that one was the better of the three that I just mentioned. I don't know Geostorm or San Andreas which one you would prefer there. I feel like they're probably on par with each other in terms of like you're there for entertainment. We're not there to judge and be hypercritical of a storyline. You're there purely for the visual effects and for the ride. CHRIS: Gotcha. Interesting. So quick question then, since this seems like the category you're interested in, Armageddon or Deep Impact? STEPH: Ooh, I'm going to have to walk through the differences because I always get those mixed up. Armageddon is where they take Bruce Willis up to an asteroid, and they have to drill and drop a nuke, right? CHRIS: They sure do. STEPH: [laughs] And then what's Deep Impact about? I guess the fact that I know Armageddon better means I'm favoring that one. I can't place what...how does Deep Impact go? CHRIS: Deep Impact is just there's an asteroid coming, and it's the story and what the people do. So it's got less...it doesn't have the same pop. I believe Armageddon was a Michael Bay movie. And so it's got that Michael Bay special bit of something on it. But the interesting thing is they came out the same year; I want to say. It's one of those like Burger King and McDonald's being right next door to each other. It's like, what are you doing there? Why are you...like, asteroid devastation movies two of you at the same time, really? But yeah, Armageddon is the correct answer. Deep Impact is like a fine movie, but Armageddon is like, all right, we're going to have a movie about asteroids. Let's really go for it. Blow it out. Why not? STEPH: Yeah, I'm with you. Armageddon definitely sticks out in my memory, so I'd vote that one. Also, for your other question that you didn't ask, but you kind of implicitly asked, I'm going to go McDonald's because Burger King fries are trash, and also, McDonald's has better ice cream cones. CHRIS: Okay, so McDonald's fries. Oh no, I was thinking Wendy's, get a frosty from there, and then you make that combination because the frostys are great. STEPH: Oh yeah, that's a good combo. CHRIS: And you need the french fries to go with it, but then it's a third option that I'm introducing. Also, this wasn't a question, but I want to loop back briefly to Armageddon because it's an important piece of cinema. There's a really great...like it's DVD commentary, and it's Ben Affleck talking with Michael Bay about, "Hey, so in the movie, the premise is that the only way to possibly get this done is to train a bunch of oil drillers to be astronauts. Did we consider it all just having some astronauts learn to do oil drilling?" And Michael Bay's response is not safe for radio is how I would describe it. But it's very humorous hearing Ben Affleck describe Michael Bay responding to that. STEPH: I think they addressed that in the movie, though. They mentioned like, we're going to train them, but they're like, no, drilling is such an art and a science. There's no way. We don't have time to teach these astronauts how to drill. So instead, it's easier to teach them to be astronauts. CHRIS: Right. That is what they say in the movie. STEPH: [laughs] Okay. CHRIS: But just spending a minute teasing that one apart is like, being an astronaut is easy. You just sit in the spaceship, and it goes, boom. [laughs] It's like; actually, there's a little bit more to being an astronaut. Yes, drilling is very subtle science and art fusion. But the idea that being an astronaut [laughs] is just like, just push the go-to space button, then you go to space. STEPH: The training montage is definitely better if we get to watch people learn how to be astronauts than if we watch people learn how to drill. [laughs] So that might have also played a role. CHRIS: No question, it is the correct cinematic choice. But whether or not it's the true answer...say we were actually faced with this problem, I don't know that this is exactly how it would play out. STEPH: I think we should A/B test it. We'll have one group train to be drill experts and one group train to be astronauts, and we'll send them both up. CHRIS: This is smart. That's the way you got to do it. The one other thing that I'm going to go...you know what really grinds my gears? In the movie Armageddon, they have this robotic vehicle thing, the armadillo; I believe it's called. I know more than I thought I would remember about this movie. [chuckles] Anyway, continuing on, the armadillo, the vehicle that they use to do the drilling, has the drill arm on it that extends out and drills down into the asteroid. And it has gears on the end of it. It has three gears specifically. And the first gear is intermeshed with the second gear, which is intermeshed with the third gear, which is intermeshed with the first gear, so imagine which direction the first gear is turning, then imagine the second gear turning, then imagine the third gear turning. They can't. It's a physically impossible object. One tries to turn clockwise, and the other one is trying to go counterclockwise, and they're intermeshed. So the whole thing would just cease up. It just doesn't work. I've looked at it a bunch of times, and I want to just be wrong about this. I want to be like; I don't know what's going on. But I think the gears on the drilling machine just fundamentally at a very simple mechanical level cannot work. And again, if you're going to do it, really go for it, Michael Bay. I kind of like that, and I really hate it at the same time. STEPH: I have never noticed this. I'm intrigued. You know what? Maybe Armageddon will be the movie of choice tonight. [chuckles] Maybe that's what I'm going to watch. And I'm going to wait for the armadillo to come out so I can evaluate the gears. And I'm highly amused that this is the thing that grinds your gears are the gears on the armadillo. CHRIS: Yeah. I was a young child at the time, and I remember I actually went to Disney World, and I saw they had the prop vehicle there. And I just kind of looked up at it, and I was like, no, that's not how gears work. I may have been naive and wrong as a child, and now I've just anchored this memory deep within me. In a similar way, so I had a moment while traveling; actually, that reminded me of something that I said on a recent podcast episode where I was talking about names and pronunciation. And I was like, yeah, sometimes people ask me how to pronounce my name. And I can't imagine any variation. That was the thing I was just wrong about because 'Toomay' is a perfectly reasonable pronunciation of my name that I didn't even think... I was just so anchored to the one truth that I know in the world that my name is Toomey. And that's the only possible way anyone could pronounce it. Nope, totally wrong. So maybe the gears in Armageddon actually work really, really well, and maybe I'm just wrong. I'm willing to be wrong on the internet, which I believe is the name of the first episode that we recorded with you formally as a co-host. [chuckles] So yeah. STEPH: Yeah, that sounds true. So you're going to change the intro? It's now going to be like, and I'm Chris 'Toomay'. CHRIS: I might change it each time I come up with a new subtle pronunciation. We'll see. So far, I've got two that I know of. I can't imagine a third, but I was wrong about one. So maybe I'm wrong about two. STEPH: It would be fun to see who pays attention. As someone who deeply values pronouncing someone's name correctly, oh my goodness, that would stress me out to hear someone keep pronouncing their name differently. Or I would be like, okay, they're having fun, and they don't mind how it gets pronounced. I can't remember if we've talked about this on air but early on, I pronounced my last name differently for like one of the first episodes that we recorded. So it's 'Vicceri,' but it could also be 'Viccari'. And I've defaulted at times to saying 'Viccari' because people can spell that. It seems more natural. They understand it's V-I-C-C-A-R-I. But if I say 'Vicceri', then people want to add two Rs, or they want a Y. I don't know why it just seems to have a difference. And so then I was like, nope, I said it wrong. I need to say it right. It's 'Vicceri' even if it's more challenging for people. And I think Chad Pytel had just walked in at that moment when I was saying that to you that I had said my name differently. And he's like, "You can't do that." And I'm like, "Well, I did it. It's already out there in the world." [laughs] But also, I'm one of those people that's like, Viccari, 'Vicceri' I will accept either. In a slightly different topic and something that's going on in my world, there was a small win today with a client team that I really appreciated where someone brought up the conversation around the RuboCop RSpec rules and how RuboCop was fussing at them because they had too many lines in their test example. And so they're like, well, they're like, I feel like I'm competing, or I'm working against RuboCop. RuboCop wants me to shorten my test example lines, but yet, I'm not sure what else to do about it. And someone's like, "Well, you could extract more into before blocks and to lets and to helpers or things like that to then shorten the test. They're like, "But that does also work against readability of the test if you do that." So then there was a nice, short conversation around well, then we really need more flexibility. We shouldn't let the RuboCop metrics drive us in this particular decision when we really want to optimize for readability. And so then it was a discussion of okay, well, how much flexibility do we add to it? And I was like, "Well, what if we just got rid of it? Because I don't think there's an ideal length for how long your test should be. And I'd rather empower test authors to use all the space that they need to show their test setup and even lean into duplication before they extract things because this codebase has far more dry tests than they do duplication concerns. So I'd rather lean into the duplication at this point." And the others that happened to be in that conversation were like, "Yep, that sounds good." So then that person issued a PR that then removed the check for that particular; how long are the examples? And it was lovely. It was just like a nice, quick win and a wonderful discussion that someone had brought up. CHRIS: Ooh, I like that. That sounds like a great conversation that hit on why do we have this? What are the trade-offs? Let's actually remove it. And it’s also nice that you got to that place. I've seen a lot of folks have a lot of opinions in the past in this space. And opinions can be tricky to work around, and just deeply, deeply entrenched opinions is the thing that I find interesting. And I think I'm increasingly in the space of those sort of, thou shalt not type linter rules are not ideal in my mind. I want true correctness checks that really tell some truth about the codebase. Like, we still don't have RuboCop on our project at Sagewell. I think that's true. Yeah, that's true. We have ESLint, but it's very minimal, what we have configured. And they more are in the what we deem to be true correctness checks, although that is a little bit of a blurry line there. But I really liked that idea. We turn on formatters. They just do the thing. We're not allowed to discuss the formatting, with the exception of that time that everybody snuck in and switched my 80-line length to a 120-line length, but I don't care. I'm obviously not still bitter about it. [chuckles] And then we've got a very minimal linting layer on top of that. But like TypeScript, I care deeply, and I think I've talked in previous episodes where I'm like, dial up the strictness to 14 because TypeScript tends to tell me more truths I find, even though I have to jump through some hoops to be like TypeScript, I know that this is fine, but I can't prove it. And TypeScript makes me prove it, which I appreciate about it. I also really liked the way you referred to RSpec's feedback to you was that RSpec was fussing at you. That was great. I like that. I'm going to internalize that. Whenever a linter or type system or anything like that when they tell me no, I'm going to be like, stop fussing, nope, nope. [chuckles] STEPH: I don't remember saying that, but I'm going to trust you that that's what I said. That's just my true southern self coming through on the mic, fussing, and then go get a biscuit, and it'll just be a delightful day. CHRIS: So if I give RuboCop a biscuit, it will stop fussing at me, potentially? STEPH: No, the biscuit is just for you. You get fussed at; you go get a biscuit. It makes you feel better, and then you deal with the fussing. CHRIS: Sold. STEPH: Fussing and cussing, [laughs] that's most of my work life lately, fussing and cussing. [laughs] CHRIS: And occasional biscuits, I hope. STEPH: And occasional biscuits. You got it. But that's what's new in my world. What's going on in your world? CHRIS: Let's see. In my world, it's a short week so far. So recording on Wednesday, Monday was a holiday. And I was out all last week, which very much enjoyed my vacation. It was lovely. Went over to Europe, hung out there for a bit, some time in Paris, some time in Amsterdam, precious little time on a computer, which is very rare for me. So it was very enjoyable. But yeah, back now trying to just get back into the swing of things. Thankfully, this turned out to be a really great time to step away from the work for a little while because we're still in this calm before the storm but in a good way is how I would describe it. We have a major facet of the Sagewell platform that we are in the planning modes for right now. But we need to get a couple of different considerations, pick a partner vendor, et cetera, that sort of thing. So right now, we're not really in a position to break ground on what we know will be a very large body of work. We're also not taking on anything else too big. We're using this time to shore up a lot of different things. As an example, one of the fun things that we've done in this period of time is we have a lot of webhooks in the app, like a lot of webhooks coming into the app, just due to the fact that we're an integration of a lot of services under the hood. And we have a pattern for how we interact with and process, so we actually persist the webhook data when they come in. And then we have a background job that processes and watch our pattern to make sure we're not losing anything and the ability to verify against our local version, and the remote version, a bunch of different things. Because turns out webhooks are critical to how our app works. And so that's something that we really want to take very seriously and build out how we work with that. I think we have eight different webhook integrations right now; maybe it's more. It's a lot. And with those, we've implemented the same pattern now eight times; I want to say. And in squinting at it from a distance, we're like; it is indeed identically the same pattern in all eight cases or with the tiniest little variation in one of them. And so we've now accepted like, okay, that's true. So the next one of them that we introduced, we opted to do it in a generic way. So we introduced the abstraction with the next iteration of this thing. And now we're in a position...we're very happy with what we ended up with there. It's like the best of all of the other versions of it. And now, the plan will be to slowly migrate each of the existing ones to be no longer a unique special version of webhook processing but use the generic webhook processing pattern that we have in the app. So that's nice. I feel good about how long we waited as well because it's like, we have webhooks. Let's introduce the webhook framework to rule them all within our app. It's like, no, wait until you see. Check and make sure they are, in fact, the same and not just incidental duplication. STEPH: I appreciate that so much. That's awesome. That sounds like a wonderful use of that in-between state that you're in where you still got to make progress but also introduce some refactoring and a new concept. And I also appreciate how long you waited because that's one of those areas where I've just learned, like, just wait. It's not going to hurt you. Just embrace the duplication and then make sure it's the right thing. Because even if you have to go in and update it in a couple of places, okay, sure, that feels a little tedious, but it feels very safe too. If it doesn't feel safe...I could talk myself back and forth on this one. If it doesn't feel safe, that's a different discussion. But if you're going through and you have to update something in a couple of different places, that's quick. And sure, you had to repeat yourself a little bit, but that's fine. Versus if you have two or three of something and you're like, oh, I immediately must extract. That's probably going to cause more pain than it's worth at this point. CHRIS: Yeah, exactly, exactly that. And we did get to that place where we were starting to feel a tiny bit of pain. We had a surprising bit of behavior that when we looked at it, we were like, oh, that's interesting, because of how we implemented the webhook pattern, this is happening. And so then we went to fix it, but we were like, oh, it would actually be really nice to have this fixed across everything. We've had conversations about other refinements, enhancements, et cetera; that we could do in this space. That, again, would be really nice to be able to do holistically across all of the different webhook integration things that we have. And so it feels like we waited the right amount of time. But then we also started to...we're trying to be very responsive to the pressure that the system is pushing back on us. As an aside, the crispy Brussels snack hour and the crispy Brussels work lunch continue to be utterly fantastic ways in which we work. For anyone that is unfamiliar or hasn't listened to episodes where I rambled about those nonsense phrases that I just said, they're basically just structured time where the engineering team at Sagewell looks at and discusses higher-level architecture, refactoring, developer experience, those sort of things that don't really belong on the core product board. So we have a separate place to organize them, to gather them. And then also, we have a session where we vote on them, decide which ones feel important to take on but try and make sure we're being intentional about how much of that work we're taking on relative to how much of core product work and try and keep sort of a good ratio in between the two. And thus far, that's been really fantastic and continues to be, I think, really effective. And also the sort of thing that just keeps the developer team really happy. So it's like, I'm happy to work in this system because we know we have a way to change it and improve it where there's pain. STEPH: I like the idea of this being a game show where it's like refactor island, and everybody gets together and gets to vote which refactor stays or gets booted off the island. I'm also going to go back and qualify something I said a moment ago, where if something feels safe in terms of duplication, where it starts to feel unsafe is if there's like an area that you forgot to update because you didn't realize it's duplicated in several areas and then that causes you pain. Then that's one of those areas where I'll start to say, "Okay, let's rethink the duplication and look to dry this up." CHRIS: Yep, indeed. It's definitely like a correction early on in my career and overcorrection back and trying to find that happy medium place. But as an aside, just throwing this out there, so webhooks are an interesting space. I wish it were a more commoditized offering of platforms. Every vendor that we're integrating with that does webhooks does it slightly differently. It's like, "Oh, do you folks have retries?" They're like, "No." It's like, oh, what do you mean no? I would love it if you had retries because, I don't know, we might have some reason to not receive one of them. And there's polling, and there are lots of different variations. But the one thing that I'm surprised by is that webhook signing I don't feel like people take it serious enough. It is a case where it's not a huge security vulnerability in your app. But I was reading someone who is a security analyst at one point. And they were describing sort of, I've done tons of in-the-code audits of security practices, and here are the things that I see. And so it's the normal like OWASP Top 10 Cross-Site Request Forgery, and SQL injection, and all that kind of stuff. But one of the other ones he highlighted is so often he finds webhooks that are not verified in any way. So it's just like anyone can post data into the system. And if you post it in the right shape, the system's going to do some stuff. And there's no way for the external system to enforce that you properly validate and verify a webhook coming in, verify that payload. It's an extra thing where you do the checksum math and whatnot and take the signature header. I've seen somewhere they just don't provide it. And it's like, what do you mean you don't provide it? You must provide it, please. So it's either have an API key so that we have some way to verify that you are who you say you are or add a signature, and then we'll calculate it. And it's a little bit of a dance, and everybody does it different, but whatever. But the cases where they just don't have it, I'm like, I'm sorry, what now? You're going to say whom? But yeah, then it's our job to definitely implement that. So this is just a notice out there to anyone that's listening. If you got a bunch of webhook handling code in your app, maybe spot-check that you're actually verifying the payloads because it's possible that you're not. And that's a weird, very open hole in the side of your application. STEPH: That's a really great point. I have not worked with webhooks recently. And in the past, I can't recall if that's something that I've really looked at closely. So I'm glad you shared that. CHRIS: It's such an easy thing to skip. Like, it's one of those things that there's no way to enforce it. And so, I'd be interested in a survey that can't be done because this is all proprietary data. But what percentage of webhook integrations are unverified? Is it 50%? Is it 10%? Is it 100%? It's definitely not 100. But it's somewhere in there that I find interesting. It's not a terribly exploitable vulnerability because you have to have deep knowledge of the system. In order to take advantage of it, you need to know what endpoint to hit to, what shape of data to send because otherwise, you're probably just going to cause an error or get a bunch of 404s. But like, it's, I don't know, it's discoverable. And yeah, it's an interesting one. So I will hop off my webhook soapbox now, but that's a thought. MIDROLL AD: Debugging errors can be a developer’s worst nightmare...but it doesn’t have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers, that can actually help you cut your debugging time in half. So why do developers love Airbrake? Well, it has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake’s debugging tool catches all your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake’s lightweight APM enables developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps and includes modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. So head on over to airbrake.io/try/bikeshed to create your FREE developer account today! CHRIS: But now that I'm off my soapbox, I believe we have a topic that was suggested. Do you want to provide a little bit of context here, Steph? STEPH: Yeah, I'd love to. So this came up when I was having a conversation with another thoughtboter. And given that we change projects fairly frequently, on the Boost team, we typically change projects around every six months. They asked a really thoughtful question that was "How do you get acquainted with a new codebase? So given that you're changing projects so often, what are some of the tips and tricks for ways that you've learned to then quickly get up to speed with a new codebase?" Because, frankly, that is one of the thoughtbot superpowers is that we are really good at onboarding each other and then also getting up to speed with a new team, and their processes, and their codebase. So I have a couple of ideas, and then I'd love to hear some of your thoughts as well. So I'll dive in with a couple. So the first one, this one's frankly my favorite. Like day one, if there's a team where I'm joining and they have someone that can walk me through the application from the users' perspective, maybe it's someone that's in sales, or maybe it's someone on the product team, maybe it's a recording that they've already done for other people, but that's my first and favorite way to get to know an application. I really want to know what are users experience as they're going through this app? That will help me focus on the more critical areas of the application based on usage. So if that's available, that's fabulous. I'm also going to tailor a lot of this more to like a Rails app since that's typically the type of project that I'm onboarding to. So the other types of questions that I like to find answers to are just like, what's my top-level structure? Like to look through the app and see how are things organized? Chris, you've mentioned in a previous episode where you have your client structure that then highlights all the third-party clients that you're working with. Are we using engines in the app? Is there anything that seems a bit more unique to that application that I'm going to want to brush up on or look into? What's the test coverage like? Do they have something that's already highlighting how much test coverage they have? If not, is there something that then I can run locally that will then show me that test coverage? I also really like to look at the routes file. That's one of my other favorite places because that also is very similar to getting an overview of the product. I get to see more from the user perspective. What are the common resources that people are going to, and what are the domain topics that I'm working with in this new application? I've got a couple more, but I'm going to pause there and see how you get acquainted with a new app. CHRIS: Well, unsurprisingly, I agree with all of those. We're still searching for that dare to disagree beyond Pop-Tarts and IPAs situation. To reiterate or to emphasize some of the points you made, the sales demo thing? I absolutely love that one because, yes, absolutely. What's the most customer-centric point of view that I can have? Can I then login to a staging version of the site so I can poke around and hopefully not break anything or move real money or anything like that? But understanding why is this thing, not in code, but in actual practical, observable, intractable software? Beyond that, your point about the routes, absolutely, that's one of my go-to's, although the routes there often is so much in the routes, and it's like some of those may actually be unused. So a corollary to the routes where available if there's an APM tool like Scout, or New Relic, or something like that, taking a look at that and seeing what are the heavily trafficked endpoints within this app? I like to think about it as the entry points into this codebase. So the routes file enumerates all of them, but some of them matter, and some of them don't. And so, an APM tool can actually tell you which are the ones that are seeing a ton of traffic. That's a really interesting question for me. Similarly, if we're on Heroku, I might look is there a scheduler? And if so, what are the tasks that are running in the background? That's another entry point into the app. And so I like to think about it from that idea of entry points. If it's not on Heroku, and then there's some other system, like, I've used Cronic. I think it's Cronic, Whenever the Cron thing. Whenever, that's what it is, the Whenever gem that allows you to implement that, but it's in a file within the codebase, which as an aside, I really love that that's committed and expressive in the code. Then that's another interesting one to see. If it's more exotic than that, I may have to chase it down or ask someone, but I'll try and find what are all of the entry points and which are the ones that matter the most? I can drill down from there and see, okay, what code then supports these entry points into the application? I want to give an answer that also includes something like, oh, I do fancy static analysis in the codebase, and I do a churn versus complexity graph, and I start to...but I never do that, if we're being honest. The thing that I do is after that initial cursory scan of the landscape, I try and work on something that is relatively through the layers of the app, so not like, oh, I'll fix the text in a button. But like, give me something weird and ideally, let me pair with someone and then try and move through the layers of the app. So okay, here's our UI. We're rendering in this way. The controllers are integrated in this way, et cetera. This is our database. Try and get through all the layers if possible to try and get as holistic of a view of how the application works. The other thing that I think is really interesting about what you just said is you're like, I'm going to give some answers that are somewhat specific to a Rails app. And that totally makes sense to me because I know how to answer this in the context of a Rails app because those organizational patterns are so useful that I can hop into different Rails apps. And I've certainly seen ones that I'm like, this is odd and unfamiliar to me, but most of them are so much more discoverable because of that consistency. Whereas I have worked on a number of React apps, and every single one I come into, I'm like, okay, wait, what are we doing? How are we doing state management? What's the routing like? Are we server-side rendering, are we not? And it is a thing that...I see that community really moving in the direction of finding the meta frameworks that stitch the pieces together and provide more organizational structure and answer more of the questions out of the box. But it continues to be something that I absolutely love about Rails is that Rails answers so many of the questions for me. New people joining the team are like, oh, it's a Rails app, cool. I know how to Rails, and we get to run with that. And so that's more of a pitch for Rails than an answer to the question, but it is a thing that I felt in answering this question. [laughs] But yeah, those are some thoughts. But interested, it sounds like you had some more as well. I would love to hear what else was in your mind when you were thinking about this. STEPH: I do. And I want to highlight you said some really wonderful things. One that really stuck out to me that I had not considered is using Scout APM to look at heavily-trafficked endpoints. I have that on my list in regards as something that I want to know what's my error tracking, observability. Like, if I break something or if you give me a bug ticket to work on, what am I going to use? How am I going to understand what's going wrong? But I hadn't thought of it in terms of seeing which endpoints are heavily used. So I really liked that one. I also liked how you highlighted that you wish you'd do something fancy around doing a churn versus complexity kind of graph because I thought of that too. I was like, oh, that would be such a nice answer. But the truth is I also don't do that. I think it's all those things. I think it would be fun to make it easy. So I do that with new applications. But I agree; I typically more just dive in like, hey, give me a ticket. Let me go from there. I might do some simple command-line checking. So, for example, if I want to look through app models, let's find out which model is the largest. I may look for that to see do we have a God object or something like that? So I may look there. I just want to know how long are some of these files? But I also don't use a particular tool for that churn versus complexity. CHRIS: I think you hit the nail on the head with like, I wish that were easier or more in our toolset. But here on The Bike Shed, we tell the truth. And that is aspirational code flexing that we do not yet have. But I agree, that would be a really nice way to explore exactly what you're describing of, like, who are the God models? I'll definitely do that check, but not some of the more subtle and sophisticated show me the change over time of all these...like nah, that's not what I'm doing, much as I would like to be able to answer that way. STEPH: But it also feels like one of those areas like, it would be nice, but I would be intrigued to see how much I use that. That might be a nice anecdote to have. But I find the diving into the codebase to be more fruitful because I guess it depends on what I'm really looking at. Am I looking to see how complicated of a codebase this is? Because then I need to give more of a high-level review to someone to say how long I think it's going to take for me to work on a particular feature or before I'm joining a team, like, who do I think are good teammates that would then enjoy working on this application? That feels like a very different question to me versus the I'm already part of the team. I'm here. We're going to have complexity and churn. So I can just learn some of that over time. I don't have to know that upfront. Although it may be nice to just know at a high level, say like, okay, if I pick up a ticket, and then I look at that churn and complexity, to be like, okay, my ticket falls right smack-dab in the middle of that. So it's going to be a fun first week. That could be a fun fact. But otherwise, I'm not sure. I mean, yeah, I'd be intrigued to see how much it helps me. One other place that I do browse is I go to the gem file. I'm just always curious, what do people have in their tool bag? I want to see are there any gems that have been pulled in that are helping the team process some deprecated behavior? So something that's been pulled out of Rails but then pulled into a separate gem. So then that way, they don't have to upgrade just yet, or they can upgrade but then still keep some of that existing old deprecated behavior. That kind of stuff is interesting to me. And also, you called it earlier pairing. That's my other favorite way. I want to hear how people talk about the codebase, how they navigate. What are they frustrated by? What brings them joy? All of that is really helpful too. I think that covers all the ways that I immediately will go to when getting acquainted with a new codebase. CHRIS: I think that covers most of what I have in mind, although the question is framed in an interesting way that I think really speaks to the consultant mindset. How do I get acquainted with a new codebase? But if you take the question and flip it around sort of 180 degrees, I think the question can be reframed as how does an organization help people onboard into a codebase? And so everything we just described are like, here's what I do, here's how I would go about it, and pairing starts to get to collaboration. I think we've talked in a number of episodes about our thoughts on onboarding and being intentional with that, pairing people up. A lot of things we described it's like, it's ideal actually if the organization is pushing this. And you and I both worked as consultants for long enough that we're really in the mindset of like, all right, let's assume I'm just showing up. There's no one else there. They give me a laptop and no documentation and no other humans I'm allowed to talk to. How do I figure this out and get the next feature out to production? And ideally, it's something slightly better than that that we experience, but we're ready for whatever it is. Versus, most people are working within the context of an organization for a longer period of time. And most organizations should be thinking about it from the perspective of how do I help the new hires come into this codebase and become effective as quickly as possible? And so I think a lot of what we said can just be flipped around and said from the other way, like, pair them up, put them on a feature early, give them a walkthrough of the codebase, give them a sales-centric demo. Yeah, I feel equally about those things when said from the other side, but I do want to emphasize that this shouldn't be you're out there in the middle of the jungle with only a machete, and you got to figure out this codebase. Ideally, the organization is actually like, no, no, we'll help you. It's ours, so we know it. We can help you find the weird stuff. STEPH: That's a really nice distinction, though, because you're right; I hadn't really thought about this. I was thinking about this from more of the perspective of you're out in the jungle with a machete, minus we did mention pairing in there [laughs] and maybe a demo. I was approaching it more from you're isolated or more solo and then getting accustomed to the codebase versus if you have more people to lean on. But then that also makes me think of all the other processes that I didn't mention that I would include in that onboarding that you're speaking of, of like, how does this team work in terms of where do I push my code? What hooks are going to run? And then what do I wait for? How many people need to review my code? There are all those process-y questions that I think would ideally be included on the onboarding. But that has happened before, I mean, where we've joined projects, and it's been like, okay, good luck. Let us know if you need anything. And so then you do need those machete skills to then start hacking away. [laughs] CHRIS: We've been burned before. STEPH: They come in handy. [laughs] So when you are in that situation, and there's a comet that's coming to destroy earth, and there's a Rails application that is preventing this big doomsday, the question is, do you take astronauts and train them to be Rails experts, or do you take Rails developers and train them to be astronauts? I think that's the big question. CHRIS: What would Michael Bay do? 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 hosts@bikeshed.fm via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeeee!!!!!!!! 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:BuildPulse: Flaky tests take the joy out of programming. You push up some code, wait for the tests to run, and the build fails because of a test that has nothing to do with your change. So you click rebuild and you wait. Again. And you hope you're lucky enough to get a passing build this time. Flaky tests slow everyone down, break your flow and make things downright miserable. In a perfect world, tests would only break if there's a legitimate problem that would impact production. They'd fail immediately and consistently, not intermittently. But the world's not perfect, and flaky tests will happen, and you don't have time to fix them all today. So how do you know where to start? BuildPulse automatically detects and tracks your team's flaky tests. Better still, it pinpoints the ones that are disrupting your team the most. With this list of top offenders, you'll know exactly where to focus your effort for maximum impact on making your builds more stable. In fact, the team at Codecademy was able to identify their flakiest tests with BuildPulse in just a few days. By focusing on those tests first, they reduced their flaky builds by more than 68% in less than a month! And you can do the same because BuildPulse integrates with the tools you're already using. It supports all the major CI systems, including CircleCI, GitHub Actions, Jenkins, and others. And it analyzes test results for all popular test frameworks and programming languages, like RSpec, Jest, Go, pytest, PHPUnit, and more. So stop letting flaky tests slow you down. Start your 14-day free trial of BuildPulse today. To learn more, visit buildpulse.io/bikeshed. That's buildpulse.io/bikeshed.Airbrake: Deploy fearlessly and fix bugs faster with Airbrake Error & Performance Monitoring. Airbrake notifiers are available for all major programming languages and frameworks, and install in minutes, with an open-source SDK-based install and near-zero technical debt. Spend less time tracking down bugs and more time developing. Visit Frictionless error monitoring and performance insight for your app stack.Support The Bike Shed
undefined
Jul 12, 2022 • 49min

345: Fire Drill

Chris is getting ready to travel, and of course, Sagewell started the day with an incident, a situation, if you will... Steph talks books perfect for vacations and feels sufficiently scarred regarding still working with moving fixtures over to FactoryBot. This episode is brought to you by Airbrake. Visit Frictionless error monitoring and performance insight for your app stack. Back to Basics: Boolean Expressions Sarah Drasner tweet Become a Sponsor of The Bike Shed! Transcript: STEPH: All right, I am now officially recording as well. Let me make sure my microphone is in front of my face. 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. So, hey, Chris, what's new in your world? CHRIS: What's new in my world? Today is an interesting day. We are recording on a Friday, which is not normal for us, was normal for a long time and then stopped, but now it's back to being normal. But it's the morning, which is confusing. Also, I am traveling this evening. I leave on a flight going to Europe. So I'm going to do a red-eye, that whole thing. So I got a lot to pack into today, literally packing being one of those things. And then this morning, because obviously, this is the way the world should play out, we started the day with an incident at Sagewell, a situation. Some code had gotten out there that was doing some stuff that we didn't want it to do. And so we had to sort of call in the dev team. And we all huddled together and tried to figure it out. Thankfully, it was a series of edge cases. It was sort of one of those perfect storms. So when this edge case happens in this context, then a bad thing could happen. Luckily, we were able to review the logs; nothing bad happened. While I'm unhappy that we had this situation play out... basically, it was a caching thing, just to throw that out there. Caching turns out to be very hard. And the particular way it played out could have manifested in behavior that would have been not good in our system, or an admin would have inadvertently done something that would have been incorrect. But on the positive side, we have an incident review process that we've been slowly incubating within the team. One of our team members introduced it to us, and then we've been using it on a few different cases. And it's really great to just have a structured process. I think it's one of those things that will grow over time. It's a very simple; what's the timeline of what happened? What's the story as to why it happened and why it wasn't caught earlier? What are the actions that we're going to take? And then what's the appendix? What's the data that we have around it? And so it's really great to just have that structure to work within. And then similarly, as far as I can tell, the first even observable instance of this behavior in our system was yesterday morning. We saw it, started to respond to it, saw one more. We were able to chase it down in the logs. Overall, the combination of the alerting that we have in Sentry and the way in which we respond to the alerting in Sentry, which I think is probably the most critical part. Datadog is our log metrics tool right now. So we're able to go through Datadog, and we have Lograge configured to add more detail to our log lines. And so we're able to see a very robust story of exactly what happened and ask the question, did anything actually bad happen? Or was it just possible that something bad could happen? And it turns out just possible. Nothing actually happened. We were able to determine that. We were even able to get a more detailed picture of who were all the users who potentially could have been impacted. Again, I don't think there was any impact. But all total, it was both a very stressful process, especially as I'm about to go on vacation. It's like, oh cool, start to the day where I'm trying to wrap up things, and instead, we're going to spend a couple of hours chasing down an incident. But that said, these things will happen. The way in which we were able to respond, the alerting and observability that we had in place make me feel good. STEPH: I like the incident structure that you just laid out. That sounds really nice in clarifying what happened when it happened in the logs. And the fact that you're able to go through and confirm if anything really bad happened or not is really nice. And I was also just debating this is one of those things, right? Right when you're about to go on vacation, that's when something's going to break. And that's like, is that good or bad? Is it good that I was here to take care of it right before, or is it bad? Because I'd really like to not be here to take care of it. [laughs] You may have mixed feelings. I have mixed feelings. CHRIS: I think I'm happy. Unsurprisingly, this exists in one of the most complex parts of our codebase. And it involves caching. And I remember when we introduced the caching, I looked at it, and I was like, hmm, we have a performance hotspot that involves us making a lot of requests to an external system. And so we thought about it a little bit, and we were like, well, if we do a little bit of caching here, we can actually reduce that down from seven calls down to one over external HTTP. And so okay, that seems to make sense. We had a pull request. We did a formal review. And even I looked at the pull request where this was introduced initially, and my comments on it were like, yep, this all looks good. Makes sense to me. But it's caching-related. So let's be very careful and look very closely at it and determine if there's anything, but it's so hard to know. And in fact, the code that actually was at play here was introduced a month ago. And interestingly, the observable side effect only occurred in the past two days, which we find very surprising. But again, it's this weird like, if A happens and then within a short period after that B happens...and so it's not quite a race condition. But it was something where a lot of stuff had to happen in a short span of time for this to actually manifest. And so, again, we were able to look through the logs and see all of the instances where it could have happened and then what did happen. Everything was fine, but yeah, it was interesting. I feel actually good to have seen it. And I think we've cleared everything up related to it and been very proactive in our response to it so that all feels good. And also, this is the sort of thing we've done this a few times now where we've had what I would call lesser incidents. There was no customer-facing impact to this. Similarly, previous incidents, we've had no or very minimal customer-facing impact. So at one point, we had a situation where we weren't processing our background jobs for a little while. So we eventually caught up and did everything we needed to. It just meant that something may not have happened in as timely a fashion as necessary. But there were no deep ramifications to that. But in each of those cases, we've pushed ourselves to go through the incident process to make sure that we're building the muscle as a team to like, actually, when the bad one comes, we want to be ready. We want to have done a couple of fire drills first. And so partly, I viewed this as that because again, there was smoke, but no fire is how we would describe it. STEPH: Nice. And that also makes sense to me how you were saying y'all introduced this about a month ago, but you were just now seeing that observable side effect. I feel like that's also how it goes. Like, you implement, especially with caching, some performance improvement, and then you immediately see that. And it's like, yay, this is wonderful. And then it's not til sometime passes that then you get that perfect storm of user interactions that then trigger some flow that you didn't consider or realize that could create an issue with that caching behavior. So yeah, that resonates. That seems right. All caching problems usually take about a month or two when you've just forgotten about what you've done. And then you have to go back in. CHRIS: Yep. Yep, yep, yep. So now we've done the obvious thing, which is we've removed every cache from the system whatsoever. There are no caches anymore because it turns out we just can't be trusted with caches in any form whatsoever. ActiveRecord, we turned off caching, Redis we threw it out. No, I'm kidding. We still have lots of caching in the app. But, man, caching is so hard. STEPH: I would love if that's in the project README where it says, "We can't be trusted with caches. No caches allowed." [laughs] CHRIS: Yeah, we have not gone all the way to forbid caching within the application. It's a trade-off. But this does have that you get those scars over time. You have that incident that happens, and then forever you're like, no, no, no, we can't do X. And I feel like I'm just a collection of those. Again, I think we've talked about this in previous episodes. But consulting for as long as I did, I saw a lot of stuff. And a lot of it was not great. And so I basically just look at everything, and I'm like, urgh, no, this will be hard to maintain. This is going to go wrong. That's going to blow up someday. And so, I'm having to work on trying to be a little more positive in my development work. But I do like that I have that inclination to be very cautious, be very pessimistic, assume the worst. I think it leads to safer code in general. There was actually a tweet by Sarah Drasner that was really wonderful. And it's basically a conversation between her and another developer. It's a pretend conversation. But it's like, "But why don't you like higher-order components?" And then it's Squints. "Well, in the summer of 2018, something bad happened, Takes a long drag of a cigarette. something very bad." It's just written so well and captures the ethos just perfectly. Like, sit down. Let me tell you a tale of the time in 2018. [laughs] So I'll include a link to that in the show notes because she actually wrote it so well too. It's got like scene direction within a tweet and really fantastic stuff. But yeah, we'll allow some caching to continue within the app. STEPH: That's amazing. So I was just thinking where you're talking about being more pessimistic versus optimistic. And there's an interesting nuance there for me because there's a difference in like if someone's pessimistic where if someone just brings up an idea and someone's like, "Nope, like, that's just not going to work," and they just always shoot it down, that level of being pessimistic is too much. And it's just going to prevent the team from having a collaborative and experimental environment. But always asking the question of like, well, what's the worst that could happen? And what are the things that we should mitigate for? And what are the things that are probably so unlikely that we should just wait and see if that happens and then address it? That feels like a really nice balance. So it's not just leaning into saying no to everything. But sure, let's consider all the really bad things that could happen, make a plan for those, but still move forward with trying things out. And I realized I do this in my own life, like when someone asks me a question around if there's something that we want to do that's a bit kind of risky. And the first thing I always think of is like, well, what's the worst that could happen? And I think that has confused people that I immediately go there because they think that I'm immediately saying no to the idea. And so I have to explain like, no, no, no. I'm very intrigued, very interested. I just have to think through what's the worst that can happen. And if I'm okay with that, then I feel better about accepting it. But my emotional state, I have to think through what's the worst and then go from there. CHRIS: Wow, it's a very bottom-up approach for your life planning there. [chuckles] STEPH: Yep, I think that's, you know, it's from being a developer for so long. It has impacted now how I make other decisions. Good or bad? Who knows? Yeah, it turns out being a developer has leaked into my personal life. I've got leaky abstractions over here. So, good or bad? Who knows? CHRIS: Leaky abstractions all the way down. Yeah, circling back to, like, I don't think I'm pessimistic per se. The way that I see this playing out often is there will be a discussion of an architectural approach, or there's a PR that goes up. And my reaction isn't no, or this has a known failure point; it is more of uh, this makes me uncomfortable. And it's that like; I can't even say exactly why, and that's what makes it so difficult. And I think this is a place that can be really complicated for communication, particularly between developers who have been around for a little bit longer and have done this sort of thing and have gathered these battle scars and developers who are a bit newer. Having that conversation and being like, um, I can't say exactly why. I can tell you some weird stories. I might not even remember the stories. Some of it just feeds into just like, does this code make me uncomfortable? Or does this code make me happy? And I tend towards wildly explicit code for these reasons. I want to make it as clear as possible and match as close as possible to the words that we're saying because I know that the bugs hide in the weird corners of our code. So I try and have as few corners. Make very rounded rooms of code is a weird analogy that doesn't play, but here we go. That's what I do on this show is I make weird analogies. Actually, we were working on some code that was dealing with branching conditional things. So we had a record which has a boolean value on it. So we've got true or false, and then we've got two states, and then we've gotten an enum with three states. So all total, we have six possible states. But as we were going through this conversation, I was pairing with another developer on the team. And I was like, something feels weird here. And I actually invoked the name of Joël Quenneville because much of the data structure thought that I had here I associate with work that Joël has done around Maybe and things like that. And then also, my suggestion was let's build a truth table because that seems like a fun way to manage this and look at it and see what's true. Because I know that there are spots on this two-by-three grid that should never happen. So let's name that and then put that in the code. We couldn't quite get it to map into the data type, like into that Boolean in the enum. Because it's possible to get into those states, but we never should. And therefore, we should alert and handle that and understand, like, how did this even happen? This should never happen. And so we ended up taking what was a larger method body with some of the logic in it and collapsing it down to very explicitly enumerate the branches of the conditional and then feed out to a method. Like, call a method that had a very explicit name to say, okay, if it's true and we're in this enum state, then it's bad, alert bad. And then the other case like, handle the good case. And I was very happy with what we refactored down to because this is another one of those very complex parts of our code. Critical infrastructure-y is how I would describe it. And so, in my mind, it was worth the I'm going to go with pathological refactoring that we got to there. But yes, I was channeling Joël in that moment. I'm very happy to have had many conversations with him that help me think through these things. STEPH: That's awesome. Yeah, those truth tables can be so helpful. There's a particular article that, of course, Joël has written that then describes how a truth table works and ways that you can implement it into your habits. It's called Back to Basics: Boolean Expressions. I will be sure to include a link in the show notes. CHRIS: But yeah, I think that summarizes my day and probably the next couple of days as I prepare for an adventure over to Europe and chat about developer spidey sense. But yeah, what's new in your world? STEPH: Yeah, that's a big day. There's a lot going on. Well, I actually want to circle back because you mentioned that you're packing and you're going on this trip. And I'm curious, do you have any books queued up for vacation? CHRIS: I do, yeah. I'm currently reading Elantris by Brandon Sanderson. Folks might be aware of his work from the highest-funded Kickstarter of all time, which was absurd. Did you see this happen? STEPH: I don't think so, uh-uh. CHRIS: He did this fun, cheeky little Kickstarter. The video was sort of a fake around...oh, it almost sounded like he might be retiring or something like that. And then he's like, JK, I wrote five new books. And so the Kickstarter was for those books with different tiered packages and whatnot. I think he got just the right viral coefficient going on. And apologies for the spoiler if anyone's not seen the video, but it's been out there for a while. So he wrote some books, and that's what the Kickstarter is for. You get some books. You sort of join a book club, and you'll get one a quarter. A million dollars seems like that will be a bunch for that. That'd be great. If he raised a million dollars, that'd be amazing. $40 million four-zero million dollars. [laughs] I'm just watching it play out in real-time as well. It just skyrocketed up. The video, I think, was structured just right. He got it onto the...it was on Reddit and Twitter and just bouncing around, and people were sharing it. And just everything about it seemed to go perfectly. And yes, the highest-funded Kickstarter of all time, I believe, certainly within the publishing world. But yeah, Brandon Sanderson, prolific author, and his stuff ends up just being kind of light and fun. And so I was reading Elantris for that. It's been a little bit slower to pick up than I would like. So I'm now in the latter half. I'm hoping it'll go a little bit more quickly and be...I'm just kind of looking for a fun read, some fantasy thing to go on an adventure. But as the next book, I downloaded a second one just to make sure I'm covered. I have a book by John Scalzi, who's a sci-fi, fantasy, more on the sci-fi end of the spectrum. And I've read some of his other stuff and enjoyed it. And this particular book has a very consistent set of reviews. I've read the reviews a few times. And everybody who reviews it is just like, "This isn't the greatest book I've ever read, but man was it a fun ride." Or "Yeah, no, best book? No. Fun book? Yes." And just like, "This book was a fun ride. This was great." And I was like, perfect. That is exactly what I'm looking for on a European vacation. The book is called The Kaiju Preservation Society, which also plays on monsters, Pacific Rim Godzilla. Kaiju, I think, is the word for that category of giant dinosaur-like monster. And so it's the Kaiju Preservation Society, which, I don't know, means some stuff, and I'm going to go on a fun adventure. So yeah, those are my books. STEPH: Nice. I've got one that I'm reading right now. It's called Clementine: The Life of Mrs. Winston Churchill, written by Sonia Purnell. And Sonia Purnell tends to focus on female historical figures. And so it's historical fiction, which is a sweet spot for me. The only thing I'm debating on is because I'm realizing as I'm reading through it, I'm questioning, okay, well, what's real and what's not? Because I don't want to be that person that's like, did you know? And then, I quote this fictional fact about somebody that was made up for the novel. [laughs] So I'm realizing that maybe historical fiction is fun, but then I'm having to fact-check all the things because then I'm just curious. I'm like, oh, did this really happen, or how did it go down? So it's been pretty good so far. But then it makes me wish that historical fiction novels had at the back of them they're like, these are all the events that were real versus some of the stuff that we fictionalized or added a little flair to. I'm in that interesting space. I also like how you highlighted that you chose a fun book. I was having a conversation with a colleague recently about downtime. And like, do you consume more tech during downtime? Like, are you actively looking for technical blog posts or technical books to read or podcasts, things like that? And I was like, I don't. My downtime is for fun. Like, I want it to be all the things that are not tech. Maybe some tech sneaks in there here and there, but for the most part, I definitely prioritize stuff that's fun over more technical content in my spare time, which has taken me a little while to not feel guilty about. Earlier in my career, I definitely felt like I should be crunching technical content all the time. And now I'm just like, nope, this is a job. I'm very thankful that I really enjoy my job, but it's still a job. CHRIS: It is an interesting aspect of the world that we work in where that's even a question. In my previous life as a mechanical engineer, the idea that I would go home and read about mechanical engineering...I could attend a conference, but I would do that for very particular reasons and not because, like, oh, it's fun. I'll go meet my friends. For me, this was a big reason that I moved into tech because I am one of those folks who will, like, I will probably watch a video about Remix in particular because that's my new thing that I like to play around with and think about. But it needs to be a particular shape of thing I've found. It needs to be exploratory, puzzle-y. Fun code, reading, learning work that I do needs to be separated from my work-work in a certain way. Otherwise, then it feels like work, then it is sort of a drudgery. But yeah, my brain just seems to really like the puzzle of programming and trying to build things. And being able to come into a world where people share as much as they do blogs and conference talks and all of that is utterly fantastic. But it is a double-edged sword because I 100% agree that the ability to disconnect to, like, work a nine-to-five and then go home at the end of the day. Yeah, go home, you know, because you remember when we went to an office and then we would go home afterwards? I have to commute every once in a while into the city and -- STEPH: You mean go downstairs or go to another room? That's what you mean? [laughs] CHRIS: I used to commute every day, and it took a lot of time. And now when I do it, I feel that so viscerally because I'm like, it's just a lot easier to just walk to my office in my house. But yes, I 100% I'm aligned to that like, yeah, no, you're done with work for the day, walk away. That's that. And learning a new technology or things like that, that's part of the job. There shouldn't be the expectation that that just happens. There's continuing education in every other field. It's like, oh, we'll pay for your master's degree so you can go learn a thing. That's the norm in every other...not in every other industry but many, many, many industries. And yet the nature of our world the accessibility of it is one of the most wonderful things about it. But it can be a double-edged sword in that if there are the expectations that, oh yeah, and then, of course, you're going to go home and have side projects and be learning things. Like, no, that is an unreasonable expectation, and we got to cut that off. But then again, I do do that. So I'm saying two things at the same time, and that's always complicated. STEPH: But I agree with what you're saying because you're basically respecting both sides. If people enjoy this as a hobby, more power to you.; that's great. This is what you enjoy doing. If you don't want to do this as a hobby and respect it as a job, then that's also great too. There can be both sides, and no side should feel guilty or judged for whichever path that they pursue. And I absolutely agree, if there are new skills that you need to learn for a job, then there should be time that's carved out during your work hours that then you get to focus on those new skills. It shouldn't be an expectation that then you're going to work all day and then spend your evening hours learning something else. And same for interviews; there shouldn't be a field that says, "Hey, what are your side projects?" Or at least that should not be an important part of the interview. There should be an alternative to be like, "Or what work code do you want to talk about?" Or something else that's more in that nine-to-five window that you want to talk about. That way, there's a balance between like, sure, if you have something that you want to talk about on the side, great, but if not, then let's focus on something that you've done during your actual work hours because that's more realistic. CHRIS: I do think there's an interesting aspect at play because the world of development moves so rapidly and because it's constantly changing. And to frame it differently, I don't think we've got this thing figured out. And so many people lament how quickly it changes and that there's a new framework every other week. And there's a bit of churn that is perhaps unnecessary. But at the same time, I do not feel like as a community, as a working population, that we're like, yeah, got it, crushed it. We know how to make great software, no question about it. It's going to be awesome. We're going to be able to maintain it for forever, don't even worry about it. New feature? We can get that in there. They're actually still pretty rare. So we need to be learning, and evolving, and exploring new techniques. I think the amount of thinking is probably good mostly in the development world. But organizations have to make space for that with their teams. And thoughtbot obviously does that with investment days. That's just such a wonderful structure that embraces that reality and also brings happiness, and it's just a pleasant way to work. And frankly, my team does not have that right now. We do the crispy Brussels snack hour, which also now has a corresponding crispy Brussels work lunch, which is one week we think about it, and the next week we do the thing. We're trying to make space for that. But even that is still more intentional and purposeful and less exploratory and learning. And so it's an interesting trade-off. I deeply believe in this thing, and also, the team that I'm leading isn't doing it right now. Granted, we're an early-stage startup. We got to build a bunch of stuff. I think that's fine for right now. But it is a thing that...again, I'm saying two things at the same time, always fun. STEPH: Well, and there might be a nice incremental approach to this as well. So thoughtbot has the entire day, and maybe it's less than a full day. So perhaps it's just there's an hour or two hours or something like that where you start to introduce some of that self-improvement time and then blossom out from there. Because yeah, I understand that not all teams may feel like they have the space for that. But then I agree with everything else you said that it really does improve team morale and gives people a space to then be able to get to explore some of those questions that they had earlier. So then they don't feel like they have to then dedicate some weekend time or off hours’ time to then look into a question. And I admit, I'm totally guilty too. I am that person that then I've worked extra hours, but it's because, like you said, if there's a puzzle that my brain is stuck on and I just feel the need to get through it. But then I look at that as am I doing this because I want to? Yes. Okay, then as long as I'm happy and I don't feel like this is increasing any concern around burnout, then I don't worry about it. MIDROLL AD: Debugging errors can be a developer’s worst nightmare… but it doesn’t have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers, that can actually help you cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake’s debugging tool catches all your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake’s lightweight APM enables developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps and includes modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! Circling back to your original question about what's going on in my world, and you mentioned scarring earlier. I feel sufficiently scarred [laughs] in regards to still working with moving fixtures over to FactoryBot. This week has really confirmed that fixtures don't trigger a lot of the callbacks, the model callbacks that exist. And so this really means that you can just create bad data that your application doesn't actually allow your application to create. So there are tests that are exercising behavior that should never exist. And then porting that over to FactoryBot then highlights that because then as soon as I move that record over and then try to create it or do something with it, then the app, the test, do the right thing and let me know saying no, no, no, we've added validations. You can't do that anymore. That has been grinding my gears in terms of trying to then translate. Because then I have to really dive into the code to understand it. And the goal here is to stay as high level as possible and not have to dive in too much. But then that means that I do have to dive in and understand more. So this has frankly just been one of those times in my career where you just kind of have to slog through the work. It's important work to be done. It'll be great once it's done. But it's a painful process. And the best way that I've found to make it more enjoyable is to be in heavy communication with Joël, who's on the project with me, just so if we get stuck on something, then we can chat with each other. And then also there's one file that's particularly gnarly. And so we moved over one test. We were successful, and which felt great because then we could at least document like, okay, when we come back to this, at least we have one example that highlights the wonkiness that we ran into. But we've decided, okay, we're done with that file. We're going to take a break. There's a lot there, but we're going to move on and give ourselves a break and do some of the easier ones, and then we'll circle back to the harder one. Which was, I think, just a bit of bad luck in terms of, like, as we're going down the list, that happened to be like the gnarliest one, and it was like the first one that Joël picked up. And so I'm going through a couple of files, and Joël is like, "What? [laughs] How are you making progress?" And we realize it's just because that file, in particular, is very hard to find all the mystery guests and then to move everything over. Finding a positive note through all of the cruft, I will say this is helping with some of my code sleuthing skills. So as I am running into these problems and then looking for mystery guests, I'm noticing ways that I can then, as quickly as possible, try to triage and identify as to why one test doesn't match another test. Some of it is more specific to the application setup, so it won't be as applicable to future projects. But then some other areas have been really helpful. Like, I'm using caller a lot more to understand, like, I know this is getting called, but I don't know who's calling you. So I can put in a line that basically outputs like, show me your stack traces to how you got here. So that's been really nice as well. So it has improved some of my code sleuthing skills and also my spidey sense in terms of it's typically mystery guests. Like when a test isn't passing, it's because fixtures are creating extra data that are getting pulled in when there are queries that are being run. But they're not explicitly referenced in the test setup itself. So that's typically then where I start is looking for what record looks relevant to this test that I haven't pulled over to my test setup. CHRIS: I appreciate you finding the silver lining, the positive bit of this. Because as you're describing, the work that you're doing sounds like I think you use the word slog, which seems like a very accurate term. But sometimes we have to do that sometimes for a variety of reasons. We end up either having to introduce new code or fix old code, but this is sometimes the work. And this is something that I think you and I share about this show is we get to show all sides of the work. And the work can be glamorous and new. And oh, I've got this greenfield app that I'm building, and it's wonderful. Look at the architecture. And I know in the moment that I'm building someone else's legacy code three years from now. [laughs] And so telling the other side of the story and providing that rounded point of view, because like, yeah, this is all part of it. Again, I don't believe that this is a solved problem, building robust software that we can maintain. And so yeah, you're doing the good work in there. And I thank you for sharing it with us. STEPH: Thanks. Just don't use fixtures in your test, I beg of you. Please don't do that to the legacy code that you're writing for future developers. [laughs] That is my one request. CHRIS: And I will maybe add on to that, sparingly use callbacks. Maybe don't use them at all, and certainly don't use the combination because, my goodness, that'll lead you into some fun times. But yeah, just two small recommendations there. STEPH: Oh, there's something else I wanted to share. I saw that Slack added a new audio feature that allows you to record the pronunciation of your name, which is the feature that I was so excited about when we added it to our internal tool called Hub at thoughtbot. And now Slack has it on their profile so that way you can upload the pronunciation. And then anyone looking at your profile can then listen to how to pronounce your name. There are a couple of other features that they released, I think just in June, so about a month ago from the recording of today. [laughs] That's weird to say, but here we are. So I'll include a link in the show notes so folks can see that feature in addition to others, but I'm super excited. CHRIS: Oh, that is nice. I also like all right, so Slack now has it. Hub now has it. But I don't have access to Hub anymore. And I don't have access to every Slack in the world yet. But here's my suggestion. All right, everybody, stick with me here. I want you to own a domain. I want you to have a personal site on it. And I want the personal site to include the pronunciation of your name. I get that that's a big ask. And I get that there are other platforms that are calling to you, and you may be writing on those. But you know what? Just stand up a little site, just a little place on the internet that you own. And if it includes the pronunciation of your name, I will be forever grateful. STEPH: I like this idea. I initially was taking your idea and immediately running with it as you were speaking it because then I wondered if everyone had their own YouTube channel. But I don't know how hard it is to create a YouTube channel. I am not a YouTube channeler, so I don't know what that looks like. [laughs] But not everybody will know how to purchase a domain. So that might be another approach. CHRIS: I think it's pretty easy to do a YouTube channel. I'm conflating a couple of things. This is my basket of beliefs about people on the internet, but I kind of think everybody should own their own little slice of the internet. And so totally, YouTube is a place where the people make some stuff, make videos, put them on YouTube, absolutely. But ideally, you own something. I see a lot of people that are on YouTube, and that's it, and so their entire audience lives on YouTube. And if YouTube someday decides to change or remove them or say Medium as an example, Medium actually, I think, does a more interesting version of this where your identity kind of gets subsumed into Medium. And I really think everybody should just have their own little, tiny slice of the internet that's there. It has their name that they own that no platform can decide; hey, we've shifted, and now your stuff is gone. Cool URIs don't change as they say, and that's what I want. And then yeah, if you can have the pronunciation of your name on there, that's extra nice. Although I say that, and I don't know that I would do it because my name feels very obvious. One day someone was like, "Oh, how do you pronounce your last name?" I forget if I actually replied with the pronunciation. Or if I was like, "I need to know what options you're considering. I'm so interested because I've really only got the one." Maybe I'm anchored. Maybe I'm biased. [chuckles] I've been doing this for a while. But I really cannot think of another pronunciation of my name. STEPH: You might hear another one that you really like, and you need to pivot. CHRIS: Oh gosh. STEPH: That's the point where you start pronouncing your name differently. CHRIS: Wow, that would be a lot. And then, I could have a change log on my personal site where people can see this is the pronunciation, and this is what the pronunciation used to be. STEPH: [laughs] I like this idea. I also like this idea that everybody has their own slice of internet land. I like this encouragement that you're providing for everyone. On a slightly different note, there's a blog post that I'm really excited to talk about. It's written by Eric Bailey, who's a former thoughtboter. It's called The Optics of Pair Programming. And given how much pair programming that I'm doing, especially with Joël on the current project, it was a really wonderful read. And it also helped me think about pairing from a different perspective because we do have a very strong pairing culture at thoughtbot. So there's a lot of nuance, especially social nuances that can go along with when you invite someone to pair with you that I had not considered until I read this wonderful post by Eric. And we'll be sure to include a link in the show notes. But to provide an overview, essentially, Eric shares that given coming from thoughtbot where we do have a very open approach to pairing where pairing sessions are voluntary and then also last as long as the problem will last...but then when you're at a new company, you could experience pushback if you're inviting someone to pair and then to consider why that pushback may exist. And some of the high-level areas that Eric highlighted are power dynamics, assessment, privacy, and learning styles. So to dive into each of some of those, there's a power dynamics of it's important to consider who's offering to pair. So if I've joined a team as a consultant, there may be a power dynamic there that someone is feeling where their team is paying for my time. So they may feel like they can't say no if I offered to pair. They feel like they need to say yes to the invitation, even if they don't really want to. Or probably a more classic example would be like, what if your boss wants to pair or someone that's just more senior than you? Then it could leave you feeling like, well, I can't say no to this person, can I? Which yes, you totally can say no to that person, but it may leave you in a place where you feel like you can't. And so, it puts you in this sort of uncomfortable and powerless position. The other one is assessment, so offering to pair with someone could feel like you are implying that you want to assess their skills or that you're implying that they're not up to the task and therefore they need your help. So then that could also place someone in an uncomfortable position. There's also privacy. So someone who isn't confident may not want someone to observe their behavior or observe how they're working. It could make them feel really anxious, which then I love that Eric points this out. Ironically, pairing is really good at addressing that lack of confidence because then you get to see how other people work through their problems or how they think, or they may also have some anxiety. Or it just helps you become more comfortable in talking and thinking through with other people. So that one is a tough one where it's hard to get over that initial hurdle. But actually, the more you pair, then the less anxious you'll feel when you pair. And then there's also learning styles because pairing really involves a lot of deep thinking but in our personal time. And it can be hard to balance both of those, and it's just not as effective for some people. So I know that even as much as I really enjoy pairing, I just need to sit with code on my own sometimes. I need to think about it. I need to run it; I need to look at it. So it's really nice to talk with someone. But then I also need that alone time to then just think through it on my own because I can't have that same deep focus if I'm also worried about how the other person is experiencing that session because then my mental energy is going towards them. So that covers a number of the social nuances that can be included or running through someone's mind when you extend an invitation to them to pair. And it really resonated with me the areas that Eric highlights in this blog post. He also talks about a couple of strategies, which I'd love to dive into as well. But I'm going to pause here and see what thoughts you have. CHRIS: Yeah, I love this post. And it got me thinking about pairing and the broader human backdrop of all of the processes and workflows that we have. Everything he highlighted about pairing feels true. Although similar to you and to Eric, I've worked in a context where pairing was a very natural, very regular part of the work and sort of from the very top-down. And so everyone pairing between developers of any different level or developers and designers or really anyone in the...it was just such a part of how we worked that no one really questioned it or at least not after the first couple of weeks. I imagine joining thoughtbot those first weeks; you're like, oh God. As I shared, I think in the previous episode that we recorded, my pairing interview was with Joe Ferris, the CTO of thoughtbot, [laughs] writing a book about good and bad code. And I was like, I don't know what anything is here but very quickly getting over that hurdle. And having that normalizing experience was actually really great, and then have been comfortable with it since. But the idea that there are so many different social dynamics at play feels true. And then as I think about other things, like stand-up is one that I think of as this very simple this is a way to communicate where we're at. And where necessary or where useful, allow people to interject or step in to say, "Oh, let me help you get unblocked there or whatever it is." But so often, I see stand-up being a ritual about demonstrating that you are, in fact, doing work, which is like, here's what I did yesterday. I don't know if it's useful. Then mention that you're working on this project. But the enumeration of look, obviously, work was done by me. You can see it; here are the receipts. It's very much this social dynamic at play. And retro is another one where like, if retro is very much owned by one voice and not a place that change actually happens where people feel safe airing their opinions or their concerns, then it's going to be a terrible experience. But if you can structure it and enforce that it is a space that we can have a conversation, that everyone's voice is welcome and that real change happens as a result of, then it's a magical tool for making sure we're doing the right things. But always behind these are the people, and feelings, and the psychology at play. And so this was just such an interesting post to read and ruminate on that a little bit more. STEPH: Yeah, I agree, especially with a comment that you made about those daily syncs where I really just want to focus on today and what you have that you're blocked on. So it's a really nice update in case there are any cross-collaboration opportunities. That's really what I'm looking for in a daily update. And so I appreciate when people don't go through a laundry list of what they did yesterday because it's like, that's great. But then, like you said, it's just like you're trying to prove here's what I've done, and I trust you; you're working. So just let me know what you're doing today, friend. So Eric does a wonderful job of also including some strategies for ways that then you can address some of these concerns and then how there may be some extra anxiety that's increased when you're inviting somebody to pair. There are some wonderful strategies. I'll let folks read through the blog post itself. There are a couple in particular that came to mind for me because I was then self-assessing how do I tend to approach pairing with someone? And some ways that I want them to feel very comfortable with that experience. And there's a couple. There's one where I recognize that I need to build trust with each person. I can't just go on to a team and expect everyone to know that I have good intentions and that I'm going to do my best to be a fun, helpful pairing partner, and that it's not a zone of judgment. And that has to be cultivated with each person. Because especially as a consultant, if I'm joining a team, the people who hired me are not necessarily the people that I'm working with. It's someone that's probably in leadership or management that has then brought on thoughtbot. And so then the people that I'm working with they don't know me, and they don't know what my pairing style is going to be. So looking for ways to build trust with each person and then also inviting them or asking for help myself. So there's a bit of vulnerability that has to be shown to build trust with someone to say," Hey, I'm stuck on a problem. I would love a second set of eyes. Would you be willing to help me out with this?" So then that way, they're coming in to help me initially versus I'm going in and saying, "Hey, can I help you?" I have found that to be an effective strategy. And there's one that I do really want to talk about, and that's not everyone is going to pair well together. Like, you may find someone who always leaves you feeling just stressed or demoralized. And while it's important to consider your role and why that's true, that does not mean it's your fault and necessarily your problem to fix. So similar to having to manage up, you may need to coach the person that you're pairing with in ways that help you feel comfortable pairing. But if they don't listen to your requests and implement any of that feedback, then just don't pair with that person. That is a very fine option to recognize people that are not receptive to your needs and, therefore, not someone that you need to then force into being a great pairing buddy. And I emphasize that last one because it took me a little while to become comfortable with that and accepting that it wasn't my fault that I wasn't having a great pairing session with people. Similar to when I'm learning from someone that if someone is explaining something to me and they're making me feel inadequate while they're explaining it to me, that's not necessarily my fault. Like, I used to internalize that as like, oh, I just can't get this. But I am now a very staunch believer in if you can't explain it to me in a way that I understand, then that's probably more on you than on me. And that has also taken me time to just really accept and embrace. But once you do, it is so freeing to realize that if someone's explaining a concept and you're still not getting it, it's like, hey, how can we try harder together versus you just making me try harder? CHRIS: I like that right there of like, if I don't understand this, it may actually be you, not me, or something to that effect. Let's get that on a bumper sticker and put that in The Bike Shed store so that everybody can buy it and put it on their cars or at least just us. But yeah, that starting from the bottom sometimes it's just not going to work great. There are even...I think what you're describing sounds a little more complicated, individuals who are personally not great at communicating or pairing or things like that. And that's going to happen. We're going to run into folks that...pairing is communication. That's just the core of it, and some folks, that may not be their strongest suit. But I think there's another category of just like different working styles. And whereas I might...judge is such a heavy word, but I'm going to use it. I might judge someone who is not doing a great job at communicating to someone else, or understanding their point of view, or striving to do that, or taking feedback. Like, those are not great things. Whereas there may just be two different development styles or backgrounds, or there are other reasons that actually they may be not an ideal fit. That said, I have definitely found that in almost every variation of pairing, I've seen work at some point. Like, when I was very early on in my career pairing with folks that are very senior, I didn't get most of it, but I got some stuff. And then folks that are very much on the same level or folks that have a deep knowledge in framework, code base language, whatever and folks that are new to it but have a different set of experiences. Basically, every version of that, I found that pairing is actually an incredibly powerful technique for knowledge sharing, for collaboration, for all of that. So although there are rare cases where there might be some misalignment, in general, I think pairing can work. I do think you hit on something earlier of there are certain folks that are more private thinkers, is how I would describe it, where thinking out loud is complicated for them. I'm very much someone who talks. That's how I figure out what I think is I say stuff. And I'm like, oh, I agree with what I just said. That's good. But I find I actually struggle. There's something I think of...maybe I'm just a loudmouth is what I'm hearing as I say it, but that is how I process things. Other folks, that is not true. Other folks, it's quite internal, and actually trying to vocalize that or trying to share the thought process as they're going may be uncomfortable. And I think that's perfectly reasonable and something that we should recognize and make space for. And so pairing should not be forced upon a team or an individual because there are just different mindsets, different ways of thinking that we need to account for. But again, the vast majority of cases...I've seen plenty of cases where it's someone's like, "I don't like to pair. That's not my thing." And it's actually that they've had bad experiences. And then when they find a space that feels safe or they see the pattern demonstrated in a way that is collegial, and useful, and friendly, then they're like, oh, actually, I thought I didn't like pairing. I thought I didn't like retro. I thought I didn't like stand-up. But actually, all of these things can be good. STEPH: Yeah, absolutely. It's a skill like anything else. You need to see value in it. And if you haven't seen value in it yet or if it's always made you anxious and uncomfortable, then it's something that you're going to avoid as much as possible until someone can provide a valuable, positive experience around how it can go. I'm going to pull back the curtains just a little bit on our recording and share because you've mentioned that you are very much you think out loud, and that's how you decide that you agree with yourself. And I think already at least twice while we've been recording this episode, I have started to say something, and I'm like, no, wait, I don't agree with that and have backed myself up. CHRIS: [laughs] STEPH: And I'm like, no, I just thought through it; I'm going to cancel it out, [laughs] and then moved in a different direction. So I, too, seem to be someone that I start to say things, and I'm like, oh, wait, I don't actually agree with what I just said [laughs], so let's remove that. CHRIS: Yep. You've described it as Michael Scott-ing on a handful of different episodes or maybe things that were cut from episodes. But where you start a sentence and then you're like, I don't know where I was going to end up there. I hoped I'd figure it out by the end, but then I did not get there. And yeah, I think we've all experienced that at various times. STEPH: That’s some of my favorite advice from you is where you've been like, just lean into it, just see where it goes. Finish it out. We can always take it out later. [laughs] Because I stop myself because I immediately start editing what I'm trying to say and you're like, "No, no, just finish it, and then we'll see what happens." That's been fun. CHRIS: This is how you find out what you think. You say it out loud, and then you're like, never mind. That was ridic – STEPH: [laughs] CHRIS: I do. Actually, now I'm thinking back, and I have plenty of those where I'll say a thing, and I'm like, nope, never mind, send that one back. [chuckles] As an aside, so we do this thing where we host a podcast, and we get to talk. But we're both now describing the pattern where we'll start to say something, and we’ll be like no, no, no, actually, not that. And I think, dear listeners out there, you probably don't hear any of this, the vast majority of it, because we have wonderful editors behind the scenes, Thom Obarski for many years, and now Mandy Moore, who's been with us for a while. And so once again, thank you so much to the editor team that allows us to, I think, again, feel safe in this conversation that we can say whatever feels true and then know that we'll be able to switch that around. So thank you so much to the editors who help us out and make us sound better than we are. STEPH: Yeah, that has made a big difference in my capabilities to podcast. If we were doing this live, ooh goodness, this might be a whole different, weird show. [laughs] CHRIS: I mean, the same is true for code, right? I deeply value the ability to make an absolute mess in my local editor and have nine different commits that eventually I throw two out. And then I revert that file, and then eventually, the PR that I put up that's my Instagram selfie. That's like, I carefully curated this, but what's behind the scenes it's just a pile of trash. So yeah, the ability to separate the creation and the editing that's a meaningful thing to have in life. STEPH: Oh, I can't unsee that now. [laughs] A pull request is now the equivalent of that curated Instagram selfie. That is beautiful. [laughs] CHRIS: To be clear, I don't think I've ever taken an Instagram selfie. But I get the idea, and I felt like it was an analogy that would work. Again, I try out analogies on this show, and many of them do not stick. But I think that one is all right. STEPH: It might even go back to pairing because then you've got help in taking that picture. So hey, you're making a mess with somebody until you get that right perfect thing, and then you push it up for the world to see. So safe spaces for all the activities, I think that's the takeaway. 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 hosts@bikeshed.fm 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:Airbrake: Deploy fearlessly and fix bugs faster with Airbrake Error & Performance Monitoring. Airbrake notifiers are available for all major programming languages and frameworks, and install in minutes, with an open-source SDK-based install and near-zero technical debt. Spend less time tracking down bugs and more time developing. Visit Frictionless error monitoring and performance insight for your app stack.Support The Bike Shed

The AI-powered Podcast Player

Save insights by tapping your headphones, chat with episodes, discover the best highlights - and more!
App store bannerPlay store banner
Get the app