00:00:12.150
Thanks everyone for coming.
00:00:15.000
Cool, so I'm going to go ahead and get started. This talk is called 'Digging Up Code Graves in Ruby.' I'll talk a bit about managing dead code and the complexity of it.
00:00:20.050
I'll dive into some examples and discuss some tools for managing and tracking down dead code in various Ruby projects and Rails codebases.
00:00:35.710
Before I get into it, a quick introduction. I'm Noah, and I work on the engineering team at Credit Karma.
00:00:41.079
I love Ruby and have been working with it for a really long time. Most recently, I've been doing Scala, so I would be happy to talk about the differences between the two after the talk as well.
00:01:00.850
Now, let's discuss technical debt. This is a term many of you are probably familiar with and have nearly discussed with your teams on a regular basis.
00:01:10.260
There's also a concept called code hygiene, which some of you might have heard of. Code hygiene is an umbrella term for anything related to the health and longevity of a codebase.
00:01:28.899
This could encompass various factors. Here's a visualization for understanding technical debt and code hygiene. Technical debt can consist of many elements apart from code hygiene, but I will mostly be discussing code hygiene today.
00:01:44.560
A few examples of code hygiene include keeping dependencies up-to-date in your project. For instance, this could involve updating the Ruby version or the Postgres version you're using, as well as any gems or dependencies in your codebase.
00:01:58.719
Refactoring code is another common aspect of code hygiene. In fast-paced environments, many of us working with Rails applications find that refactoring is important for maintaining good code hygiene.
00:02:07.180
Ensuring that documentation is accurate and complete is also considered code hygiene, even though documentation itself is not actual code.
00:02:12.400
This includes keeping your REST API documentation or any internal project documentation updated.
00:02:24.950
Managing dead code is also a crucial aspect of code hygiene, which is what this talk is primarily about. There are many more examples that fit under the umbrella of code hygiene.
00:02:41.870
So, what about dead code? Dead code is another term we often hear. We likely have a general understanding of what it means, but I will discuss two distinct definitions of dead code today.
00:03:05.840
According to Wikipedia, in computer programming, unreachable code is part of the source code that can never be executed because no control flow path leads to it. Sometimes, unreachable code is referred to as dead code. However, dead code can also refer to executed code that has no effect on the output of the program.
00:03:40.610
This distinction is important. An example of dead code is an addition function that takes two arguments to perform an addition operation but includes a second line that performs an unnecessary action, which won't impact the result. Although this aspect is harmless, it can lead to inefficiencies in larger applications.
00:04:04.670
In a more complex system, if we have a piece of dead code causing an expensive operation or network call, it can cause the user to wait unnecessarily. The second aspect of dead code is unreachable code, which can stem from logical errors in conditional statements.
00:04:44.090
Another example could be code left intact for preservation purposes that is no longer needed. Tools like Git are excellent for explaining changes, and data operationally never triggering another condition may lead to redundancy.
00:05:13.240
Feature toggles, often used for canary testing, A/B testing, or operational testing, can also introduce dead code into your codebase. They provide a way to iterate quickly on a product while obtaining quantitative or qualitative metrics.
00:05:41.260
However, the downside of adopting feature toggles is that they can push costs onto development teams. The toggles can be implemented as simply as a table in your relational database along with a wrapper around querying various toggles' states.
00:06:09.200
Many companies also invest in internal tooling or use third-party services that provide great UIs for toggling features. The most common strategies I've seen involve using these toggles at the edge, perhaps in front-end applications, to toggle button color or copy.
00:06:45.980
On the other hand, using toggles across the stack to modify internal behaviors may lead to the risk of dead code.
00:07:06.090
There are both pros and cons to using feature toggles. A significant advantage is that you can essentially say goodbye to feature branches; you can merge behind feature toggles or flags. This can lead to deploying developmental work to production while iterating on it live.
00:07:44.180
One further benefit is that it enables agile methodologies, allowing the release of experimental features to a smaller user base without extensive upfront development. It also offers stakeholders control over product functionality through various panels managing different feature state flags.
00:08:08.290
Conversely, feature toggles represent a potential source of dead code and can introduce varying states across different environments if not managed properly.
00:08:55.780
Maintaining backward compatibility becomes necessary with any code changes to support different versions. When turning a flag on or off, fragments of code may become inconsistently managed across environments.
00:09:48.610
What if nothing is done? Ignoring dead code may not break the application, but there are costs associated with inaction. Over time, it can become increasingly challenging to work within a cluttered codebase.
00:10:35.080
In terms of costs, letting dead code persist can lead to wasted application cycles, making it slow for users unnecessarily. This can occur in database queries or APIs that aren't needed anymore.
00:11:18.600
For new engineers onboarding onto a project, a cluttered codebase will prove arduous to navigate. As well, changing portions of unusable code can become burdensome during updates or tests.
00:12:37.790
There's a fantastic quote by Martin Fowler. He compares feature toggles to inventory which comes with carrying costs, thus teams should work to keep that inventory low.
00:13:26.140
Finally, I want to summarize strategies for managing dead code effectively. The Ruby standard library provides a unique and experimental library called Coverage, which is an efficient tool for tracking code usage within larger codebases.
00:14:00.070
Some experimentation platforms offer the capacity to log or warn when code is unused for extended periods, indicating it is likely to be considered dead code.
00:14:50.220
Lastly, addressing existing dead code as part of any new feature release is vital to keeping your code healthy. Thank you for your attention. I'll be taking questions afterward off stage.