Learning About the Fundamentals of Good Code
I’m a support engineer at SalesLoft. Day to day, I troubleshoot problems in the app. I also get to write code with our product delivery teams. This is my favorite part of the role because about a year ago, I graduated from a coding bootcamp with zero experience writing code on the job.
There are tons of benefits that come with collaborating with product delivery teams. I always gain a new level of understanding about Ruby and Rails, writing tests, using Git and deploying code. These moments of collaboration also give me the opportunity to showcase valuable contributions that I can make to the our code base.
Recently, I wrote some code to prevent SalesLoft users from sending invitations to existing members of their team. For example, let’s imagine that Beyonce, Kelly and Michelle are on a sales team called Destiny’s Child. Beyonce shouldn’t be able to invite Michelle to join the team again because Michelle is already on the team.
In this blog post, I’ll share what I learned about writing good Ruby code. First I’ll share my initial solution to this problem. Then I’ll share the final solution I worked out after receiving feedback.
When I first wrote this, I felt so good about getting the code to work. I didn’t realize how problematic it was that the invite method is doing too many things. It…
- grabs team_id from my invitation_params
- queries the User model using that team_id
- plucks user_id from the collection returned from that query
- plucks email
- uses Ruby’s set intersection operator to find common values between the values in emails and invitation_params[“emails”]
- removes the emails in matches from invitation_params[“emails”]
- sends invitations to people who are not already on the team.
After receiving constructive feedback from the software engineers on one of our product delivery teams, I reached a better solution. Check it out below. Then I’ll share what my three major takeaways were.
Smaller methods: I divided my initial solution into smaller methods . As a result, each one has fewer than five lines of code! Imagine another person reading this code. They’d need very little context to understand what it’s accomplishing since it’s simple and straightforward.
Meaningful method names: Now that the code is divided into smaller methods, it’s easy to give each method a name that’s meaningful and unambiguous. For example, the method name grab_emails_from_team gives the reader a very clear idea of what it’ll accomplish.
Keep it simple: At first, I wrote code to find emails that exist in the invitation params and on the team. Then it removed those emails from the invitation params. It turns out that not all of that was necessary.
All I needed to do was remove any emails that appear in my invitation params with ruby’s subtraction operator for arrays.
So what’s the value in writing good code? Many experts argue that it saves time, money and makes your application more sustainable over time.
Software engineer and author Sandi Metz argues that writing short methods is a major contributing factor to good object oriented code (Rules, by Sandi Metz, 2013). In her 2013 talk she shares that when software engineering teams follow this rule (among others) their application code includes small objects with fewer dependencies which enable the application to survive future changes.
Similarly, Robert C. Martin, another noted software engineer and author, argues that clean code can save you from wasting hours and resources. In his book titled Clean Code, he includes an entire chapter on the best practices for naming methods. One of them is to use “intention-revealing names.” He shares that poorly named methods introduce code that’s not explicit enough. This leaves the reader with outstanding questions that should be answered by the code, but aren’t.
My experience collaborating with our product delivery teams has been very rewarding. What I’m learning from them about writing good code are the building blocks to becoming a great software engineer.