Code Quality

Little Snippets

Little Snippets

by Xavier Noria

In the talk "Little Snippets" presented by Xavier Noria at EuRuKo 2016, the focus is on the finer details in coding practices that contribute to writing clean, maintainable, and efficient code.

The main topic centers around the subjective nature of coding preferences and styles, drawing on personal experiences in programming and code review. Noria emphasizes the importance of understanding that coding is not a black-and-white discipline, and a significant portion of coding practices is driven by personal intuition and preferences.

Key points discussed throughout the talk include:
- Subjectivity in Coding: Noria stresses that coding conventions often arise from individual preferences that can vary significantly among programmers. Acknowledging this subjectivity can help foster better discussions about code quality and practices.
- Conciseness: He emphasizes the value of writing concise code, which translates not only to fewer lines of code but also to improved performance. By using specific API calls, developers can streamline their code without unnecessary complexity.
- Readability and Maintainability: Noria discusses the principle that writing clear, readable, and maintainable code is crucial for future developers who may work on the codebase. Techniques include avoiding redundant constructs and simplifying expressions where possible.
- Coding Conventions: The importance of following conventional coding practices in Ruby is noted. For example, using self redundancy is often unnecessary, and best practices should guide method definitions to enhance clarity.
- Empathy in Coding: Developers are encouraged to write code that is intuitive and easier for others to maintain, emphasizing the need for clear documentation and thoughtful variable naming.
- Code Structure and Organization: Noria discusses the significance of structuring code logically to align with how a reader would understand it, thus enhancing navigability and comprehension throughout the codebase.
- Tools for Imposing Standards: He recommends tools like RuboCop, which can help maintain consistency in coding styles and practices across a project.

The talk concludes with a reminder of the collaborative nature of programming, encouraging developers to reflect on their practices and improve their craft continuously. Noria thanks the community for ongoing contributions to coding languages, attributing the evolution of code quality to shared knowledge and effort, ultimately inspiring better coding practices among peers.

00:00:03.930 So our next speaker, Xavier Noria, from Barcelona, is an independent Ruby on Rails consultant and also a core team member for Ruby on Rails. His contributions are evident whenever you see contributors listed on rubyonrails.com or when you reference a constant without requiring it. That's thanks to him. So, enjoy the talk, and see you in a minute.
00:02:29.230 In this talk, I will express some opinions. I want to address a common issue in discussions, whether online or in person. We often phrase things such that it sounds like we are asserting absolute truth with our reasoning. Life isn't an axiomatic system; there is no first-order logic universally applicable here. Most of the time, what happens in discussions is that you have some preference, and then you back it up with reasons that make sense to you. While your preference is your choice, those reasons are derived from your background, trade-offs, and how your brain works. Therefore, when two people discuss their rationales, the intersection of their reasoning and trade-offs can often be quite fuzzy.
00:04:19.599 Let’s do an example with code. Here we have a hash, and we will look at the difference that the placement of a comma can make. Do you feel the tension with that comma? For some people, the version with the comma at the bottom is preferred because it makes it easier to add something later. If there’s a comma everywhere, adding another line becomes cleaner since you only modify that line. However, other people might see the absence of a comma as a missing element. To them, the brain parses that as a missing element. This is a classic example where there’s no right answer; it all depends on personal preferences. Acknowledging this subjectivity in discussions is essential. I believe it’s valuable to introduce phrases like “in my opinion” or “in my view” to soften the absolute tone in our discussions.
00:05:31.870 Thus, for this entire talk, I’m going to convey that everything I say is purely my viewpoint. If at any point my statements seem light or conditional, let it be known that they are grounded in my opinion. Now, let’s begin discussing conciseness. Conciseness means using as few words as possible without including unnecessary information. This definition mainly applies to natural language, but it perfectly translates into programming languages as well. For example, we could take a collection, sort it, and take the last element. However, a more concise way to express the same task is to use the method that gets the maximum value. The original method requires you to sort the entire collection, but that’s not necessary to achieve the goal.
00:06:03.550 Conciseness in programming translates to choosing the most specific API calls. Often, this involves writing less code, which not only makes the logic more apparent but can also provide better performance. If you specifically ask a library or an interpreter for what you need, it can optimize the solution better than if you provide it with unnecessary context. For instance, when getting keys from a hash, there’s an API to do so directly. However, I often find this more verbose style still prevalent. I suspect this is due to the inertia of developers not thinking about using the existing API instruction sets provided by their frameworks. This situation is something that I commonly see in practice.
00:07:20.700 When reviewing Rails applications, I often come across this kind of verbosity, and I believe that developers writing this kind of code might be visualizing calls they are used to. For instance, an Active Record query often resembles SQL queries instead of using the provided abstractions. Developers often write literal strings instead of relying on defined symbols or modules. This may occur out of a visual habit. A frequent example is when you check for a substring, using a regular expression appears lightweight, but that's misleading since regex adds a layer of complexity and side effects.
00:09:07.740 If you do not need those side effects, you can simply use a predicate method that is more concise for checking matches. Thus, performance benefits can arise from using simpler, more direct methods that do not carry the overhead of regular expressions. While I often prefer using concise methods, I can't ignore that the original method may read better for some; it’s crucial to remember that there’s tension between performance and readability, and not every case is black and white.
00:10:06.100 As we explore more examples, let’s discuss using redundant self in Ruby. Most of the time, there’s no need for this redundancy; therefore, the conventional code should not include it. With method calls for instance, the `new` keyword does not require qualification via self when used properly. It’s common, however, to still see self used before variable names that are one or two letters. I find this puzzling since it reflects a certain cognitive bias, perhaps related to length and visibility. The Ruby community has conventions that prioritize not using self, but it is interesting to see how other programming languages differ in their handling of these concepts.
00:11:22.210 This leads us to a principle I like to include: writing maintainable code is crucial. Consideration for readability goes hand in hand with writing enjoyable code. When you’re programming, avoid constructions that complicate readability. For example, using `unless` can confuse readers because the brain generally has a harder time processing negations. Saying 'name is present' rather than 'unless name is blank' is more straightforward. The practice of avoiding double negatives will lead to more intuitive code.
00:12:57.680 This section leads to discussing clarity with backslashes in literals which add unnecessary complications. Writing clean and clear code can involve avoiding backslashes unless absolutely necessary. In Ruby, there are plenty of ways to formulate strings and regular expressions without over-relying on them. Backslashes can give a heavy look to your code, which distracts from readability. Trying to reduce visual clutter in the code is an aim we should strive for.
00:14:03.910 Next, when we load files or handle configurations, think of the clarity and transition to newer syntaxes or methods that achieve ease of understanding. For example, using relative paths can often lead to confusion. With advancements in Ruby, addressing pathing has become simpler. The transition to newer methods like `require_relative` provides a clearer navigation of the codebase. Writing code as if the maintainer could be your future self is good practice, but it's also wise to consider who will interact with the code base after you, providing empathy through your coding decisions.
00:16:41.490 In the interest of empathy, writing readable and well-documented code will improve the experiences of future maintainers. Think about your fellow developers; writing code isn’t just for your benefit. You’re writing to foster understanding for someone down the line, maybe someone who isn’t as familiar with the context you are steeped in. When you've maintained a codebase and encountered perplexing snippets, you realize how detrimental it can be when many logical branches are hard to decipher.
00:18:02.860 Next, I want to talk about the structure of code. When you're coding, structuring things intuitively is vital. For example, when you're defining ordered attributes or methods, think about the logical sequence your brain will follow. If there are chronological relationships, encode those concepts in your code. This kind of organization helps your audience parse through your logic much easier and can aid in understanding the flow of your application. Consistent naming and ordering improve maintainability and understanding.
00:20:28.870 As conversations about constructs become frequent, remember that repetition in teaching can also clarify complex topics. By reflecting the sequence in how you organize methods and arguments, you tighten the connection between your aim and the result. Thus, as you navigate through method definitions, align the order you present attributes with how someone might logically reason through the flow of data.
00:22:00.890 We all constantly make choices about our coding conventions, and while it’s easy to lean towards familiar styles, awareness of effective communication methods can prompt your code to convey adequately. As we’ve seen, clarity tends to stretch beyond just using fewer lines of code but embracing the heart of what the code needs to accomplish while being considerate of maintainability and readability.
00:24:11.770 Moving into discussions on precision, highlighting the importance of well-considered names for methods and variables is vital. Make it obvious; if your code traverses multiple sections, include hints about what structure it follows and provide context where necessary. Regular expressions deserve respect for their capabilities, but when misused can lead to confusing results. Ensure that the intent is well established when employing complex patterns.
00:26:45.650 Being precise and conscious about readability keeps the relationships between different parts clearer. When it comes down to the nitty-gritty of details such as managing relationships in a database or documenting code appropriately, the effort spent ensuring clarity will make significant differences to those reading your code in future.
00:29:00.490 In the same breath, we’ve learned that style guidelines aren’t necessarily rigid rules but contextual nuances. Adopting tools like RuboCop to encourage consistency will yield dividends in preserving clarity and coherence throughout your codebase. Ultimately, striving for excellence in craftsmanship is summed up by encouraging a greater sense of community in coding practices and coding style.
00:31:30.530 I appreciate your attention and hope this journey through coding practices invites reflection and empowers you. In closing, I want to extend my thanks to those who contribute to the evolution of coding languages and frameworks. Continuous improvement relies on our collaboration, driving forward our understanding of how best to communicate through code.
00:34:20.930 Thank you.