 I think we're gonna go ahead and get started. Thank y'all all for coming. Welcome to RubyConf. Appreciate all being here. So my name is Megan Tew. I'm a senior software engineer at CallRail and I'm the co-organizer of the Atlanta chapter of Rails Girls. Yeah, Rails Girls is awesome. And you can also find me at Megan Tew on Twitter and on GitHub and most other internet places. So talking about finding beauty in the mundane, that could probably mean a lot of things. But what I mean as software developers, we can't love every part of our jobs, right, as much as we'd like to. Some things are just less fun than others. Some things are boring or tedious, but we have to get them done. But how can we love our jobs more? How can we love these parts of our jobs more? Well, I believe that in order to fully relish our work, we must understand the frustrations we have with these aggravating parts of software development and change our perspectives in order to better our teams and our software. And I believe the best change in perspective we can have is to focus on empathy. When we're constantly mindful of the people that are touching our code and our software and what their needs are, we'll build better systems for everyone. Because at the end of the day, all computer problems are people problems. And if we solve our computer problems like we solve our people problems, we'll build better software and develop better connections with our team. And you love your team, you love your work. One reason that's important for us to address our feelings about these mundane parts of development is to combat tech debt. So when you move fast and you create quickly, you're probably not doing your best work, things the best way, right, and things to the slip through the cracks. And much like financial debt, that tends to pile up when it's not dealt with. And the reality is we've all got it, but most often we don't have time to deal with it, right? And the way we emotionally cope with the reality of tech debt is a spectrum. So on the one end, it just doesn't faze you. You don't really think about it, you just know it's there. And on the other end, it gnaws at you with every waking moment and you're constantly thinking about the ways you need to improve. And unfortunately for me, I'm more of the latter. I've definitely spent sleepless nights thinking about untested code and classes that needed to be restructured. And that's because I know we can do better. All of us here, not just me and my teams. And we can be better at building software and being happy with our applications. But the reality is that it's really not that flashy, right? We can't constantly be churning out these huge, exciting new features. That pace just isn't sustainable. And we get hit with a good dose of reality when our applications start breaking under the weight of our tech debt. And as we grow as developers, it's important to learn the value of resolving tech debt. In the book, Apprenticeship Patterns, David Hoover, and Adelaide Oceanier, one of their most notable pieces of advice is what's the grungiest task that your team has been putting off for months? It'll be the one that everyone complains about and no one wants to tackle. Tackle it. Don't just hold your nose and force yourself to do it. See if you can creatively resolve the problem in a way that exceeds people's expectations and makes it fun for you. And at the end of the day, what we do is so much more than code, best practices, or prestige of any kind. It's about respect for our teammates, both current and future. It's about respect for our users. It's about respect for ourselves. At the end of the day, when we learn to love our work, hopefully our teams can be happier and work better together. So how can we change our perspective on these mundane tasks? I'm gonna cover five different things that we could probably all stand to like a little bit more and ways to enjoy them. So the first is updating dependencies, be it packages, gems, or libraries. All of our applications rely on other people's code to run. And but why do we often resist updating gems and updating rails? Well, maybe your gem file is better measured in feet in lines of code. Maybe running bundle update rails creates like a never ending cascade of red bundler text. Where would you even start with that? It could take days, weeks, months, maybe years for a big Rails upgrade, right? And if your code runs, why do it at all? Common concerns, right? For one, we get more secure applications. When we think about what our users want, they want their data to be secure, right? But outdated dependencies are a huge risk. There could be vulnerabilities hiding in an old version of a gem that you're using and you might not even know it. But updating patch versions is low risk and high reward. Because they usually only contain fixes, you can be pretty confident knowing things won't break. So you get that added stability that you wouldn't have had otherwise. And it's just a small amount of effort. Upgrading is also a great way to gain more exposure to the open source community. So as you are tracking down issues with new versions, you're reading change logs, you're finding out if support for a new Rails version is gonna be added to a gem that you're using, you'll become more in tune with where the community is gathering and how they communicate. And this process just gets easier over time. So it's easier for you to contribute back to OSS2 when you're ready. Upgrading also gives us valuable debugging experience. So you get to dig through your system and find breakages in a safe environment. So as you're upgrading and you see a test of yours fails, as long as you know something's broken, it's not going to production, right? So users won't see it and there's significantly less urgency in fixing the problem. It's a very safe way to gain valuable debugging experience that I often recommend for junior developers. And you get that valuable debugging experience without the stress of tracking down production issues with that temporal sensitivity. It also gives us use of supported versions when we're upgrading. So you don't wanna be in a situation where you find a bug in a gem that you're using only to find that the version isn't supported any longer and no one's gonna resolve the bug that you and you have to fork it and then you're stuck maintaining that fork and trying to update it on your own. It's a tedious process but keeping up to date with things means there's likely gonna be someone else there to lend a hand. And then especially like relevant thing is that Rails 4.2 right now is only receiving severe security matches, like not even minor or moderate. And that still doesn't seem like a very old version, right? And according to the Rails documentation, like 5.1 is the only one receiving bug fixes officially. Like if you're not up to date, you're not getting those fixes. And again, upgrading is, for some people, like pulling teeth and nails. But when I'm updating, I try to feel like I'm fighting a boss in a video game. So our application's health is the princess in the castle that I've gotta go save. And I like to take small steps when I'm doing it. Go gem by gem. And that's like knocking out the small guys first. And each gem that successfully bundles without any conflict, that's like a headshot straight to the boss. That's like really valuable damage that's going little by little. It's really important. And then finally, when I'm updating Rails, that's the boss itself. When all the bundler like dependencies resolve, I get all that green text, it feels awesome. This is a job well done and you can learn a whole lot in the process. It feels really good to be more in tune with your system and the greater community. So next up to tackle is writing documentation. Now this is one we all know we should have, but usually don't have enough of, if any. And so for the purposes of this talk, I'm referring to internal documentation for your code and your systems. So like comments in your code or a wiki. And like it has the express purpose of explaining the way that your company's technology works to the people that work there. Why don't we often like writing docs? Well, imagine like you're just finished writing a big feature and it's all tested and QA give the green light, but there's no documentation. So all, if like another developer wanted to come on the project and work on this feature, they'd just left reading code and there's not a lot of clarity there, right? You wouldn't want that to necessarily hold up the feature release, right? But we used to thinking in computer languages for the better part of the day, it can be like really difficult to transition into thinking in human languages to write documentation. I could really give like an entire talk on writing good documentation. So I'll try to keep this brief, but one of the many reasons they're great is they help spread knowledge. And like we know commonly like knowledge is power, right? But especially so in the context of complicated systems that we need to work together to try to understand. Docs also help prevent silos. So without good documentation, knowledge stays concentrated in the brains of those that built a feature. So with good documentation, anyone can go and read about how a thing works. It's empowering. They also help make onboarding easy so that developers that are new to your team spend much less time digging for answers and to certain questions or even worse clues to where those answers might be and then they just keep digging at Infinitum. But, and aiding and onboarding is really just one way that they help others. It helps them in a myriad of ways, including developers that are new to your team. So at any level of experience, like how can you navigate a new code base without direction, right? Docs provide that direction. They also help your current teammates work with the things that you've made so they know which end is up. They're not just going in blindly trying to fix things without any guidance. Docs are that guidance. Future developers too, they help. So these are people that you don't even know yet. Maybe everyone on your team right now knows exactly how the complex authentication system you've built works. So that's great. But what about when a new developer comes on? Will they be able to look at it and just instantly know? There's gotta be a way to share that knowledge and the best way is having documentation. They also help support team members at your organization, diagnose and fix problems so that they can go out and actually find out how something works instead of having to ask a developer all the time. They get that agency and they're more independent. And of course, docs will help you too. If I told you that I'd never written documentation so that specifically I would be able to answer the question, wait, how does that work again? I would definitely be lying. You in a few months will have as little context as someone that's brand new to the code base. You will definitely forget why you made certain development decisions. So documenting now will prevent lots of future frustration. As we see writing docs are a concrete way to help other people that are touching our code and using our systems. And we use a little empathy. We have direction and purpose in writing docs. By writing documentation, we empower other people. We say, here, this is yours too. You get to share in that knowledge. So maybe at your organization you don't have any docs or much at all, right? Where's a good place to start? I like to make a glossary of common terms. So usually business domain specific lingo at your company. So I like to include common acronyms. A good example of this is that our company, we deal with lots of telephony things. So there's a modal where users can purchase a phone number from us. We call that the new number modal, an NNM. But someone knew the organization's not just going to know what an NNM is, right? So we have that glossary defined, have it defined in the glossary so they know exactly what that means. Another good thing to do with this glossary is include links to the code base that use these terms heavily, things like database models. Where you can define the term in English and then define it in the code. And that's that bridge in the gap of knowledge, right? This makes it really easy for new folks to follow the conversation early and no terms that are relative to the system so they can understand what everybody else is talking about quicker and they can be more productive faster. Another technique that's really helpful is commenting your code as you write it. A lot of times when we think about writing documentation we think about going and documenting like entire systems or big parts of systems at once and that's the kind of thing that takes like a long time and that's what gives writing documentation a bad rap. But if you're writing code, if you're writing comments as you write your code it's a lot simpler. So if you're making a new class just add a top level comment describing what it does and how it's used. And you can do the same thing for new methods too where appropriate. And there are tools like Yard that turn your code comments into navigable documentation that are super helpful because when you can have a specific place to point developers that are new to your team they'll feel ecstatic. Because our jobs are to solve hard problems not spend valuable resources deciphering spaghetti systems. It feels really good to have those basics laid out for you so you can be more effective at your job earlier. Another thing new developers love seeing when they're entering an app for the first time is tests. So specifically you're writing on made tests as part of the software development process as our jobs as developers not leaving that up to QA. And this helps devs that are new to your team because reading tests is a really great way to find out how parts of a system work. Diving blindly into a code base without tests feels kind of like this. Like maybe if I make a change this will continue to work but I don't really know. And we can just hope for the best that it'll keep on spinning. But why don't we like writing tests? So as Rubyists often in the community like it's generally accepted we write tests right it's a big part of our time but I still run into the mindset a lot that it's like it's not worth your time I just gotta keep writing code I don't have time to write tests or I hear the argument that you can just test the code in your browser and verify that it works why would I need to write tests. For when we get more reliable software you will find the actual points of failure as you're building. You can only hand test so many like paths a user might go down but with automation it's so much easier. And you have a easy way to tell when something goes awry. Tests also allow for refactoring with peace of mind. So this is that red green refactoring model so that if you're starting refactoring with a green test suite you can make a change run your tests. If they're green great just keep refactoring but if they're red you can address a problem as it comes up and not wait until it goes to production and then fix it till it's green and keep going. And this acts as a safeguard so that we know we won't be breaking our software. And finally so far in my development career I don't think any feeling has matched the first time I made a test pass and that a group of test pass and it feels really good because you know that the thing you made works you can actually verify it. And as developers we're not the only ones that need testing. So chefs in fine dining restaurants don't just make up menu items on the fly. They do many rounds of meticulous tests first to make sure that the dish is just right and only then once it passes tests can that product be served to customers. And this is how we should be developing our software because we care about our users. We don't want them to eat crappy food or use crappy software. Properly tested applications make you calmer and make work more peaceful. This dog is like I am at one with my application. And you can make this feeling possible for your teammates when you ensure that your code that you're working on is properly tested. So another way we can build better systems for happier developers is linting. So if you're not familiar it's the automated process that goes through each file line by line ensuring your code conforms to a specific style. And it raises warnings when it doesn't so you can go fix them. Think tools like RuboCop for us or ESLint if you're using JavaScript. Why don't we like linting? I think it tends to get a bad rap because it's really tedious and you're making all these small changes. And it can be a lot, especially when you see something like this which is an actual RuboCop warning output from a project I've worked on in the past. And an amount of problems that large seems insurmountable. What benefit could we possibly have by taking the time to do this? Believe it or not I actually think this is an opportunity for a quick win. So if you go file by file step by step it'll feel like nothing. So I have a co-worker that when she's starting a new task she likes to check out every file that she's gonna have to touch and then lint all of them first so that she can have a clean workspace to start and she's already bettering the code base in the process. Just like when you're updating gems breaking it down into smaller parts it's totally doable. So you can just lint a file, PR that and then repeat and you'll have things shipping on a regular basis and you're constantly making things better for your co-workers. Linting is also an opportunity to learn best practices especially if you're just getting started with programming linters are a really great way to know how you're doing because they're built on community created style rules writing your code with the help of linters ensures that your work conforms to commonly agreed upon practices. And it also gives us a more consistent code base. So when all your code conforms to the same style rules it'll be much easier to read. Developers on your team won't get whiplash from going from one file to the next because they're written in totally different styles. Instead it will be seamless and your code can flow from one file to the next. When you finally get it your code base is cleansed. So something that really helps in the linting process is establishing a style guide. So you can sit down with your team and decide how you'd like your code base to look. New code won't raise nearly as many linter errors because you've decided to write your code in a certain way. And you can tune your linters to the team that your team agrees on. So if you don't like Rubikop's rule of that line it should be 80 characters long. Maybe they should be 160. You can put that in your Rubikop config. And to make linting more fun I like to think of it as playing Galaga. So you're a spaceship pilot and your mission is to defeat all the enemy aliens. And your score goes up with each one you kill. With each linter warning you resolve you're making your code base better and better. And at the end when you beat the game you defeat all the aliens you feel free. And your code base is a lot more consistent. And it's so much easier for new teammates to get working in your applications because they'll know how the system is supposed to work. They'll spend less mental energy trying to figure out the styling that you've come up with, right? By using a little empathy. Knowing that our teammates want to read a consistent code base makes linting way more rewarding. So our final task for the day is refactoring. A lot of folks don't like refactoring but this is the goal, like something with the... All right. I guess we're doing that now. Thank you. Yeah, refactoring. All right, so I think we're gonna go back and get started. Thanks for sticking around. Never a dull moment at Rubikop. We get a fun fire alarm interruption. Yes, exactly. My talk is actually on fire. All right, so thanks for coming back and sticking around. I wanted to talk about refactoring and how it's a great way for... It's our final task that we were gonna be covering. So refactoring, anything with the goal of making your code easier to understand. So this could be big or small within one file or across multiple classes. You could be changing syntax or actually changing the overall architecture of your system. Why do we not tend to like refactoring? Well, for one, it's hard, right? Especially for those bigger system-wide refactors. Why refactor a bunch of old, complicated code when you can be writing fun new features somewhere else? You can take a lot of time, especially if your refactor was to span tens of hundreds of classes with like hundreds to thousands of lines each. Well, for one thing, sometimes it's just necessary to do, right? And one sign of this is that you're spending all day staring at a couple files, just trying to figure out how they work and how they work together, what they're doing. At the end of the day, we all want readable code. Our jobs are to solve hard problems, not spend valuable resources deciphering spaghetti code. If possible, we should always take the opportunity to make our and our teammates' lives easier by reducing that mental strain that comes with having to process complexity. And I think refactoring's pretty cool. It's the closest we have to visual art, especially for backend developers like me that rarely, if ever, touch the front end. As we cut up, move around, and transform our code, we're artists. So the next time you're refactoring, picture your code as paint and your files at the campus and make something stunning. So let's take this method that finds the first n prime numbers when you pass n as an integer. So if we're starting from the top, you've got a couple different conditionals over there, unless this, okay, we're gonna do that thing, instantiate a new array, and then we've got a for loop. I thought this was Ruby. So with just a few small changes, we can make this so much easier to read, right? Clearly, lines five and six, return this if this, turn this if this, and then find the first n prime numbers. That's so much simpler. So that now the next person to come along doesn't have to sit for a while trying to decipher what this method does, right? By refactoring, we are showing respect for our teammates. And as Rubyists, we use a language optimized for human readability. Why not take advantage of Ruby's strengths? It feels so tangible. I can just take this thing and move it around and play with it and have something beautiful at the end. Refactoring fills me with this wonderful sense of joy. And when I finish a big refactor, it's kind of like everything is wonderful and I have to take a minute and marvel at the beauty that I created with my own two hands. I just took an ugly thing and made it so much better for everybody else coming after. This code is beautiful, I think, and software is too. And getting to make it is a real gift. And I feel really lucky to do this for a living and I hope you do too. So, let's wrap up. The question we originally set out to answer, how can we love our jobs more? Well, we updated gems and we defeated a boss in video game. We wrote documentation and made a glossary and commented our code as we went and it was pretty easy. We tested and we concocted delicious fine dining meals for our users. We lented and we played Galaga, right? And we refactored and became artists in the process. The thing is that this change takes time. This isn't some grand tale about forcing your coworkers to love upgrading rails because if I could do that in one spell swoop, I would be a hypnotist and not a developer. Instead, it's about gradually building habits. If we take a few minutes to do these things per day or even per week, we'll build better practices into our development routines. And a trait that's great to build into our habits is a common thread for reasons to do all the tasks we've covered. Empathy, we wanna help other people. When we're constantly mindful of who else is touching our code or our software and what their needs are, we'll build better systems for everyone and we and our teams will be happier to use them too. I'm a firm believer that we build better software through empathy. But that's not all. It pays to be positive. So these boring parts of development are actually my favorite because I can do lots of little things to help my fellow developers in countless ways. I choose to be optimistic about what we can accomplish, what kind of great change we can bring together through better development practices. And because I believe I can make these good changes, I go out and I try to do them. It's so much less daunting when you have a positive attitude about it and I encourage you to do. So go, spread these tactics to your team. You will be a hero when you tackle these tasks but you don't have to be the only one because together we can make big changes for the better step by step. So go out, love yourself, love your team and love your software. Again, I'm Megan Tew. I work with CallRail and we are hiring so if you're in Atlanta or would like to be, please come chat with me. You can find me at Megan Tew on Twitter which is where I'll be posting my slides online today and then they'll be up on the RubyConf website later. I'll be taking questions off stage and in the hall so feel free to please come chat, say hi. Thank you.