00:00:21.579
Welcome back! Lunch is officially over. I hope you all cast your votes for Rotom or another city. Of course, it doesn't really matter. I have a couple of announcements to make before we get started, so please listen carefully. There have been care packages taken from the men's room — perhaps you thought they would be better utilized in the ladies' room. They were placed there for a reason, so please leave them where they are. Also, some of the care package baskets were taken away entirely, so we kindly ask you to return them.
00:01:07.610
A couple of things for tonight: if you don't know where to have dinner yet, the hotel provides a 20% discount in their restaurant, and you get a discount at the hotel registration tonight.
00:01:21.440
Ramon, one of the organizers, has reserved 20 places at a karaoke place if that's something you're interested in. Just come to the front later or find Ramon to sign up; it's first come, first served. Danielle has also reserved 20 places at Back to Ha, which is a nice, hip place in the 5th district. I highly recommend it.
00:01:47.590
Aaron is not in the room, so I will make this announcement for him. He is doing a tour — more details will be mentioned later. Finally, please do not put glass bottles in the bins; there are crates next to the fridges for recycling purposes. Now, we will have two talks, and after those, there will be a brief break. I would love for everyone who has ever coached at a Rails Girls event or organized a Rails Girls event to come to the front so we can take a nice picture.
00:02:33.469
So that's everything for the announcements. Now, Anna will take the stage. She started with Rails in 2015, contributed to an open government project, fell in love with Rails, and has never looked back. She will take us on a refactoring journey.
00:03:04.369
Hi everybody, I'm Anna, and I'm going to speak about refactoring, improving Ruby. This year, Ruby is turning 25, and I think I've changed more than Ruby itself. A lot of great Ruby code has been written in these 25 years, but also Ruby code that was not that great. The purpose of my talk is not to criticize bad code or to show you the most impressive refactoring ever, but to share my experiences and what I learned while refactoring Ruby code.
00:03:21.439
Before going into concrete examples, allow me to introduce Preheat, which is what I’m working on and from which I took most of the examples. Preheat is a really old Rails application that started in 2005, before the first Ruby release, just to give you an idea of how old it is.
00:04:03.000
The Preheating project I'm working on is called Open Build Service, commonly abbreviated as OBS. From now on, I will speak a lot about OBS. OBS is a system that builds and distributes packages from sources. It is an open-source project, and the packages can be interacted with freely. The URL to the GitHub repository and the URL to the external instance are available on the slide, so feel free to check them out.
00:04:14.669
Now that everyone is up to date, let’s refactor some Ruby code. The first example I want to share is what I like to call 'the scary comment.' This is real code from an OBS class introduced in 2011: the Note class. As you are laughing, you may have already discovered the scary comment: 'stay away from this!' That was my reaction when I read the comment!
00:04:58.500
Now, seriously, what does 'stay away from this' mean? It's a comment that raises questions. I had no idea what it meant, but according to the documentation, it is used for public methods that should not be publicly consumed. It's not just a comment; it has a side effect because it hides the method from the documentation. Given that 'stay away from this' accompanies a no-doc comment, I wondered what it meant.
00:05:53.990
The specific method was used internally. It was marked for the equal method. I discovered through my digging that it wasn't private. Instead, it was used in an internal context, guided by the definition of 'protected.' The protected keyword allows methods to be called only within the defining class and its subclasses. So I made the comment an internal method to clarify that it was indeed an intentional inclusion.
00:06:41.629
From this experience, I learned that comments can be a bad idea. And of course, sometimes comments are necessary, but there are many instances where we could describe the code better. I also learned what a no-doc comment is, having seen it primarily in the Rails code for methods that are public but not intended for user reliance. And of course, I learned about the usefulness of 'protected.'
00:07:45.100
Now, let's talk about reusing code in OBS. Let’s say we have some code to be reused that uses two parameters, and we need it twice. The reasonable way to handle this would be to define a method and call it twice.
00:08:00.000
However, in OBS, what we had to do before followed an outdated pattern. We used an improperly defined hash for the parameters — with one parameter as a key and the second as the value. We iterated over this hash and placed the reusable code inside, but that gets messy pretty quickly.
00:08:19.650
The new approach is changing the strings in the keys to symbols and subsequently transforming it during the iteration, leading to more readable and maintainable code. A better option is to use symbols directly to minimize conversion processes and improve clarity, ultimately leading to a more efficient code snippet.
00:09:03.090
Next, let’s review logical conditions in code as another example of necessary refactoring. Here’s a concrete example from OBS where we add errors based on checking multiple conditions. The first condition adds an error if both one value and another are true, while the second specifies that if at least one of those values is true, we should add an error.
00:09:40.010
What we need is an exclusive OR condition, sometimes referred to as XOR, which will return true only if one of the conditions is true and false otherwise. Refactoring this section simplified the code to be much more concise and readable while maintaining its intended logic. Now, if we implement an error-check, it only raises if either of the stated conditions is true and helps ensure clarity in intent.
00:12:00.700
Now, I have another example: the concat plus unique logic in OBS. Here we work with the 'if list packets' situation. This is essential to allow for checking against nil values and ensuring things are handled properly in the code.
00:12:38.500
Before, these operations were more cumbersome, and we processed data using undesired methods. My goal was to simplify this into clear, maintainable code. As we want to remove duplicates while concatenating lists, I proposed a new 'union' method to streamline the process. It turns out that when we used a pipe operator in Ruby, we found it could simplify this method greatly.
00:13:24.240
This method improves efficiency over the existing solutions, especially if we utilize it for three or more elements. My suggestion to replace concatenate with a clear union method still stands as it provides better efficiency overall while keeping code simple and understandable.
00:15:25.740
Now, I went ahead and asked the Ruby core to explore this option. I presented the idea but faced some resistance initially. Christian, a colleague, had thoughts on why the original concat might remain preferred due to readability concerns. This led to some discussions, and I realized that it's essential to approach these scenarios constructively and collaborate effectively even when opinions differ.
00:16:43.970
Eventually, the nuances led to the idea that different environments have different expectations. I found that I needed to take patience into account when working on code with others. Not everything can happen at once, and persistence matters.
00:18:17.090
What have I learned throughout this process? It taught me the importance of engagement in the larger community, with real-world implications on Ruby development. The Ruby open-source community is thriving and contributes significantly to my understanding and ability to work within it. Learning from one another is invaluable, and the importance of patience also strikes home.
00:20:48.839
I encourage you all to get involved in Ruby, contributing upstream where possible. We grow together in those experiences, and while some processes may be challenging, the results and friendships that emerge simply reinforce the value of this community. Thank you!