 Hey, everybody. Thanks for coming to working compassionately with Legacy Code. My name's Amr Shah. I'm a developer at Share Progress. Share Progress works for nonprofits. We do some front end and data science consulting for them. And I hack on our social media analytics platform in Ruby and Sinatra. And Sinatra, not Sinatra, but Share Progress is a fantastic place to work. It's got an awesome remote first culture, so I would love to talk to you more about it if you're interested. And this is a talk about compassion. So you might think that I'm a very compassionate person, and you might think that I'm a vegetarian. Maybe I meditate regularly. Maybe I hang from trees. Well, I meditate. You might think that because I'm up here on stage that I think I'm some kind of rock star, and maybe I think I'm a compassion rock star, but I'm not. I'm just like you guys. I'm a software developer. And since you all are software developers, you know that although you might spend a few minutes every day celebrating a victory, most of the day you spend failing. And when it comes to compassion, I'm no expert. I fail all the time, just like software. But that's OK. I got a word for that, and that word is learning. So I've been looking back on some experiences that I've had with legacy code. And I want to tell you, as maybe not that grizzled old rock star, but I want to tell you about those experiences and how, looking back on them, I feel like now I see where I could have used some compassion and had a better time inheriting frustrating legacy code application. So this is the story of two apps, how I inherited two applications of the same company. And the story of these two legacy code applications are two stories that ended quite differently. So I was hired by a company to, based on some meager iOS experience that I could write on a resume and fool somebody into thinking that I should be trusted, I was hired to take on an existing legacy code application that had been bought from some contractors and never been pushed out to production because it just didn't look solid enough. And so I took a look at this app that was supposed to be used internally by our company's repair technicians out in the field. And as you can guess, it was a disaster. The UI was both boring and subtly mysterious. It was impossible to get a workflow right. You got lost every time. And the solutions under the covers were the problems that were just not the ones that needed to be solved. Like, for instance, if you wanted to share data between two people using the app on different iPads, you had to put them into a room together and set up a peer-to-peer connection and then zap that data over the network in email. The app relied on frameworks that were completely out of date and unmaintained and dead. And if I said them to you here now and you know anything about iOS, you probably wouldn't have heard of them because they don't matter anymore. And instead of doing constant communication with the server, the mobile app had to be synced every 24 hours into one huge data dump. And if you didn't do that syncing, then you weren't allowed to continue. You just had to wait. And sometimes the request to the server would take minutes to come back, and sometimes it wouldn't come back at all. It was a soul-crushing spectacle. Developers as second-class citizens and users as a despised and outcast underclass. Now, I wasn't the first in-house developer to work on this project. I was the first full-time in-house developer to be hired by the company. But there was another contractor who had come in for a couple months and she had tried her best with this and she was someone with a lot of mobile experience and she had a lot of options and so when it came time to decide whether to stick around, she decided to get out. But I had her notes and her commits and I thought I should call her up and ask her for some advice because I kind of felt like, well, I was lost. She was really nice to talk to me over the phone but her advice was chilling. Kill it and start over. So now that I had two people on my side and decided to go to management and say, hey, this app isn't in production. We don't need it. We don't need everything that could come with it. So why don't we start again? And to my surprise, they actually went for it. So there you go. Legacy code problem solved. Everybody go home. But I told you I inherited two applications and the other application was in production and this was a Rails web app that we use internally every day. Four or five users plugged into this all day long posting records, basically taking the paperwork generated by the in-the-field technicians and pushing it into our system. And these data entry operator people, I really sympathized with them because this app was built by the same contractor as the first app that I mentioned and it had all the same problems. The UI was unforgiving. You make a mistake and there was no way to fix it. You just had to resort to desperate measures. And enough of these desperate measures and finally the data just didn't look right. It was completely out of order. And the ironic thing about it was that some people in the office would check in once in a while and they would notice that things weren't quite right. But that message didn't filter up to the top because there was a culture in the company that if you see something, better not say anything. When I took a look at the insides of this Rails app, this is what I saw. No automated tests. Stuck on Rails 2.3 and Ruby 187, both of those end of life. You talk about fat models, I had 1500 line models of Ruby code, 300 line methods. You could inject SQL through the search filters and there was something called an authorization loophole. And basically the app had both a customer portal and an administrator portal and of course you had a customer role, you'd use the customer portal. Well, you could get to the admin portal just by typing in the URL if you could guess what it was. So here I was with this app that my manager said was pretty solid. And I was terrified that I was the only person in the whole organization, in the whole building, I was the only person who knew that it could come apart at any minute. I was so afraid, I really felt like I was gonna get ulcers. I was terrified. But I displaced my fear by focusing, fixating on blame. I hated the developer who wrote the app. And what's more, I found his name, you know it's in the git commit, and I knew that he was a big deal locally in my community. And now he was the CTO of a company that touted its software practices and I thought, how dare you? Here you are extolling the values of TDD on Twitter and you left me with an app that had no tests. Here you are writing a book on microservice restful architectures and you left me an API with one route. I also was angry because I remembered that I had applied to his company and you can guess what happened. I didn't hear back at all. And while that didn't bother me much when it happened, I mean I had enough offers. Now I was thinking, well what's so bad about me? Why am I not good enough to work at your company but I'm good enough to clean up your mess? So that was the emotional state I was in. But to move on with my life, I gave this person an unflattering nickname based on his unique style of git commit message. Note the misspellings of ASDF, that's what I like. And I put on a brave face and I ordered some books and these are great books and these helped me a lot and you might notice the title working effectively with legacy code. And this talk is about the same things only focused on emotions. Well I worked nights and weekends, I was hacking, squeezing, extracting and injecting just like Martin Fowler. And I felt like I was a battlefield medic and here I was in the jungle with this patient and I didn't know if we were gonna get out alive. And in the brief moments where I could get away from work and I could get out and meet some of my non-technical friends, I would tell them every day at work is like pushing a sick man through a desert. No, you can't have any more water. Yes, you have to keep, you can't lie down, do you wanna die? Well, as time went by, we shed our heavy coats, me and this old man in the desert and we replaced them with a set of seven, a set of seven highly predictable controller methods. We wrapped our parts' throats in a spartan layer of plain old ruby objects and we thought we'd never make it alive out of this wasteland, but then over the horizon we saw them, the first flickers of green, then a veritable forest of passing our spec examples. We fell to our knees in an embrace, my partner and I, this legacy code base and I. And looking back on these times, I began to realize that all those days I was angry at my computer, I was staring into the face of the only person who knew what I was going through and that person was my legacy code. And I thought about this legacy code applications and just software in general, these are our partners. So how accurate is this? Like is our code, or our code bases our partners? Well, they're not people, but what are people like? People are unpredictable. You never know how people react. You don't know if they'll come through for you and you don't know if their idea of coming through is exactly what you think it might be. It's hard to predict what people will do, partly or I think mostly, because you've never had the same experiences as them. And while someone can tell you about their experiences, you'll never know. The history that someone has before they met you is the black box, it's completely opaque to you. And for that reason, people are really difficult to control. I mean, are you trying to control people? If you are, please stop, because not only is it terrible to everybody, it's also something you can't do. The only thing you can do with people is to surround yourself with the good ones and trust that they'll do their best. And I wonder, are we running into so many emotional problems when we deal with legacy code because we want to control it? Well, we ought to be able to, but it's so complex. And let's wonder, why do we want to control code? And I think it might be because we might feel like someone's controlling us. So you might be thinking, okay, well, that's fine, whatever, but code's not people. It doesn't have feelings. It doesn't do its best. It just does what it does. And congratulations, you're right, you solved the universe. But even though code's just ones and zeros, you're not. And while you can spend all day taking out your frustration on the legacy code that you inherited, maybe that's not the best thing for you. And maybe cumulatively, that won't lead to the best life that you can have. And as software developers, we are really good at adopting processes and coming up with our own to hack our brains and to do things better than we would without the guides of the process. And I suggest that we try one of those. So here's an idea that comes from cognitive behavior therapy. It's called cognitive restructuring. And the idea here is to notice when you have these automatic thoughts that come straightforward with their negative emotions and just completely force you into a way of thinking that's bad for you. You might have seen Laura's talk. This kind of thing is hardwired into our brain, but we don't have to be a slave to automatic thoughts. Inside potentially harmful automatic thoughts are cognitive distortions. Things that are just wrong ways, fallacies about getting information from the world. Take your automatic thoughts when you notice them and force them to some kind of socratic interrogation and then come up with a rephrasing. So here's a couple examples from the story I just told you. I looked at ASDF and I thought this guy is a liar. He's a fraud. He says that he values one thing, but in reality, he does something else. But this is a cognitive distortion called labeling. I took an event that had one reading, that he was a fraud, and I immediately went to that one, to that reading. I didn't think that maybe ASDF learned a lot through this experience. Maybe it was the experience of building an app with so many problems like this that taught him the value of software practices. I mean, after all, we've all been there. Another automatic thought that came to mind was that I was rejected. I was worthless. I wasn't good enough for ASDF. But well, there's some mind reading going on. I don't know why he didn't write back to me. And also there's some labeling. Why do I have to label myself as worthless? You know, if you look at that time, the resume and the cover letter that could send him just didn't provide the evidence that I was a strong fit for that company. And if they had better candidates, of course they should choose someone else. Why pick a gamble when you have a sure thing? Nothing wrong with that. Automatic thoughts are so dangerous because they keep us from taking in advice and other ways of thinking that could really help us. Here's a tweet that I tweeted during those months of trudging through the desert. You're not fixing someone else's mess. You're fixing a mess. That was a quote that I found in an article about legacy code. Well, instead of taking that to heart because that's really good advice, I just got real snarky. I still wish someone else hadn't made such a mess. Well, I thought I was clever to say that. And of course it's a little bit clever. It's a clever turn of phrase, but it's dumb is what it is. Because instead of learning the lesson, I just threw it back. So I went looking for that article and it's a great article. It's by a guy named Jan Dudulski and there's the link right there. And that quote, you are not fixing someone else's mess. You're just fixing a mess. That points to a fallacy that software developers all of us tend to engage in. And that's that code belongs to somebody. The fallacy of code ownership. And that's ASDF's code. And when I work with it, I have to think about him. I don't. Code is person agnostic. You wanna talk about ones and zeros? Code doesn't care who's working on it. You're here. You should work on it. So now you all know that you ought to, that you ought to like legacy code or at least stop hating it. And you ought to eat that for lunch every day. And you ought to go jogging every morning at six and run a five K. And you ought to floss every night before you go to bed at 10 and you can have that on your tombstone. And then you might wake up to that. And, but I wanna tell you that you don't have to force yourself to like legacy code. Actually legacy code is pretty cool. I love legacy code. Yeah, you're like, what is this? Why would someone say that that's so unnatural? I love legacy code because I love learning. And I think that most of you or all of you out there like to learn. And the reason I know that is because the list of things that we need to learn never stays still. In fact, those are things that you need to know just to be barely competent. But in a couple of years, that list will be different. So learning is probably one of the things that you aspire to and that you pride yourself on doing all the time. And I think legacy code teaches you well and you learn better and more with legacy code for a couple of reasons. And one is that it's in production, you can't throw it away. It is of such value that you cannot get rid of it because in that story I told you there was one app that wasn't in production. All right, fine by. But the one that was, we had to improve it. And when code is in production, you have to make a choice. You can't sit back and just research all the different possible. There was one app that was, you've got to make a choice. This thing is so valuable, you can't let it go. And you might think that you learn when you do all this research, you say, oh, I got to learn about this, so I'm going to spend the weekend reading and maybe hacking a little bit on a toy project. But you learn when you actually make a choice and you especially learn when you fail. Legacy code forces you to make choices and fail. Legacy code will have regressions. That's how you learn. I love legacy code. Why else do I think that legacy code is a good teacher? Because it's there. It's something to work with. If you've ever had, I bet you have this problem all the time is the problem that I have. You're at home, you're hacking on something that you really want to learn, a new framework, a new language and all you can manage to build with it is basically a toy application that does what you wanted it to do but does it in a really straightforward way. And how do you actually get to the point where you feel like you're an expert? Well, production use cases are difficult because somebody needs this. And a legacy code application is solving problems in production. It's there, it does what it does. All you have to do is push it around a little bit. Doing refactoring can be kind of mechanical. Just extract this piece, move it to a new file, rename this name. You can do it while your brain kind of does other things. And that's great. Working with legacy code can be meditative. It can feel good. You can go home after a long day of working with the legacy project and feel relaxed and rested. And that's not a new idea. I've actually watched a couple great talks on that. So if legacy code is something that riles you up inside and you take it home every night and you feel angry and scared, I want you to consider why that might be. And I think that it might be because of a toxic culture that you might work in or some aspects of a toxic culture. Specifically, blaming. If you feel afraid that you're gonna be blamed or something goes wrong with this legacy app, you gotta wonder if that is an environment where you can do your best work. But the sad thing is that we as software developers, we actually promote a culture of blame. And we do that by wanting to be the one person who knows about software. Especially if you work in a small company where you were hired as the first developer like I was, you like that management will hear your opinion and say, we don't know any better than you, we'll do what you say. It feels good, you feel like you have autonomy. You can sneak some autonomy by saying you're the only one who understands. But being the only one who understands means you're also the only person who has any responsibility when things go wrong. And that is a tough spot to be in. So if you're in a culture like this, it might be tempting to sneak that autonomy by saying I'm the only one who gets it, but really you'd be better off by trying to change the culture. And when you're in a situation like this, there are two things, there are two questions that I want you to ask yourself continually and keep in your mind. And one of them is what can I change? Because if you can get other people in your organization to take some responsibility for understanding code and take some responsibility for the ideas that you have and the decisions that you might make, then you can spread out the pain of this legacy project and make it a teamwork exercise, something that brings you closer together. And if you can take on some of their responsibilities so that you can show that you are not just a master of code and a code wizard, but somebody who cares about where this company is going, then you'll have a much better time making it through with legacy code. But the other question you should ask is how much more of this am I gonna tolerate? Because sometimes you're only one voice and you might be a new voice. And changing the culture is a big thing. It's not something that we can all do by ourselves. And it's not a failing of ours if we couldn't. So draw that line in the sand and say to yourself, how much more of this and what particular, what particular kinds of culture can I accept? It's okay to have an exit strategy. It's okay to say to yourself, I'm ready to move on if things don't improve by this day or I'm ready to move on if this doesn't work. Don't feel bad about trying to improve the culture by being ready at the same time being ready to get away. So I promised in the abstract, which I wrote a long time ago, that you could let go of your anger and your fear about legacy code and you could find joy. And that's actually a really easy promise to make because you hear that all the time. It's true. Let go of your anger and your fear and find joy. But I wanna leave you with something else. And that's that as developers, you get to work with Ruby all day. We are really, really lucky. I mean, I'm sure you've heard that. I hope you think it because Ruby is a joy to code. It's not perfect, but it's a joy to code. And if that weren't enough, Ruby culture and the Ruby community comes with something that's really great. I'm sure you've seen this before. Maths is nice, so we are nice. So you look at that logically, it doesn't make a whole lot of sense. What is that so doing there? What does it have to do with the fact that math is nice, that we are nice? And why do we need that? Well, I'll be honest. Being nice is so easy and so valuable that any reason is good enough. The fact that math is nice, okay, we'll all be nice. I was so lucky to shake math's hand the other day and I felt so happy about that. And I don't want anything bad to happen to him ever. But if math hit his head or something and he wasn't nice anymore, it's okay. We'd all still be nice. There's a great idea that's getting a lot of traction. You hear it a lot now and it's very important is that code is communication. And of course, code is in a very literal way, communication with your computer, communication all the way down to the internals of how your computer works. But that's not why math's invented Ruby. He invented Ruby so we could communicate better with other developers and with ourselves, with future, Amur, and future you. And our tools that we use every day and the apps that we make and the products that we make, we use them to communicate with our users through good user experience and good design. We communicate with our managers and our stakeholders through QCumper and BDD. And we communicate with ourselves and with other developers on our team through our actual code. So when you're communicating with the people around you, with your bosses and your managers and the developers on your team and the users, people who mentor you, people who you mentor, when you communicate with your partners and your children and your friends and all the people around you, be kind. Be generous with your kindness. Spread that shit everywhere. Because kindness is the most valuable thing in the whole wide world that you get unlimited amounts of for absolutely fucking free. Thank you. We have plenty of time, I think. We can do some questions. Or we can, I don't know. Let's try for questions first. Oh, here's one. So the question was how long did it take to refactor the app? I think the refactoring, I guess, is always in process, but we had to get test coverage over the whole app so we could get it through those critical upgrades to get it off a bend of life. And I started the job in an April and I left the following March, but I don't think I started working on that app full-time until around June. So it took some time. I think I, oh, so the question was, this is a really good question. What forced me to actually think back to that time and reevaluate the way that I approached those days emotionally? And I don't have a great answer for this. I think I always knew that I was making the wrong decisions emotionally. I mean, I think anger feels bad. Anger and fear feel bad. And I think that having some distance kind of brought me to the point where I wanted to ask why I acted like that or thought like that internally. And then also I got to give Ernie credit. I really enjoyed the talks on humane development and this idea that we should both seek to make our workplaces, our work cultures, a place where we would want to work, where people have autonomy and freedom and they respect each other and believe that everyone is coming from a good place. And I remember that I didn't feel like that at that job. And so feeling like I had both the opportunity to seek those places out and I could make that happen at work, I think made me wonder how I could have done it better at that job. So the question is what kind of advice for compassion would you have if you were the writer for the crappy legacy code? And I think the advice is the same. Go easy on yourself and remember that past you was someone who hadn't learned all the things that the present you has learned. I think that kind of sums it up. Yeah, so the question is, it's a more technical question about the chicken or egg question about legacy code. So are you going to try to write tests for the existing code or are you going to try to change the code to make it easier to test? And the answer is that you have to do a little bit of both and it's difficult and a little bit scary. There are some really good technical recommendations that are outlined by Michael Feathers and working effectively with legacy code. Michael Feathers actually sees legacy code as code without tests and it's a great book and you should check it out. The main recommendation of his that I was unable to actually do, something that I didn't do that I wish that I could have was that when you're adding tests to a legacy code project to start with the new feature, add tests for the new feature and then add tests to the code around it and gradually sort of increase the test coverage by producing these islands of covered code. And that way you can feel like, well, this code is fairly solid and then as you refactor, you can lean on that code as you start to improve the health of the overall code base. I wasn't able to do that one because I didn't know Rails when I started working with this application. So I had a lot to learn and testing was one of those things. And the other reason was that we had to get the entire application into a safe spot to get through an upgrade. So the new feature was upgrade, so that was everything. Okay, well the first answer, okay, the question is, do you have any specific advice on how to be compassionate to your manager? And the first answer is no. But one thing that I would like to do a better job of is realize that code is only a tool for accomplishing something bigger, for serving users in a better way and providing some kind of value. And because we really like code, we can fixate on code and just say, I'm gonna focus on how I can make this code better and then that code just being better makes us feel better. But few people besides developers at the organization are gonna feel that way or think that way. And it would be good for us as developers to step out of thinking about code first and think about the overall strategy of the organization, what its mission is, and how we could best provide value. So sometimes the best thing for the code is not the best thing for that purpose right now. Oh gosh, okay, so the question is, do I have any advice about being compassionate in personal relationships in general? I think the lead-in to this talk was all about how I'm not a compassion guru and I don't know a lot more than other people. I think just focusing on the value of compassion for everyone you meet and you see and especially the people you spend lots of time with is just gonna be better for everybody. So I think if you're keeping that at the forefront of your mind, like how can I be more compassionate here than you'll be thinking about things like let me listen to them and wait until they've completely said everything they need to say. Let me see how they need to be cared for in a feelings way before we get down to what's actually the best rational course or something like that. So I guess always look at people as big balls of feelings and think about how you can help them with those. So the question is what to do when you see a need for refactoring in code that was written by somebody who you currently work with? And I think that in that situation, not that I've had this opportunity but in that situation it would be great if you can come to that co-worker and say here's some ideas about how we can improve this code, let's do it together. And through a pairing session where maybe they be the driver, they do those refactorings and you learn about how to communicate what you think makes better code and they learn how to do that kind of refactoring. So I think that the more you can empower people to be in control of their own products, the more they can feel like they have a stake in what matters. All right, well, thanks everybody. I'd love to talk to you afterwards individually. So just seek me out anytime right now or later and thanks so much for coming and have a great lunch.