<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Matheus Richard</title>
    <description>The latest articles on DEV Community by Matheus Richard (@matheusrich).</description>
    <link>https://dev.to/matheusrich</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F290618%2Fc6efccd9-41d9-4bc6-98ad-45a37d48474e.png</url>
      <title>DEV Community: Matheus Richard</title>
      <link>https://dev.to/matheusrich</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/matheusrich"/>
    <language>en</language>
    <item>
      <title>TIL: JavaScript's void Operator</title>
      <dc:creator>Matheus Richard</dc:creator>
      <pubDate>Fri, 21 Jan 2022 14:30:38 +0000</pubDate>
      <link>https://dev.to/matheusrich/til-javascripts-void-operator-58ni</link>
      <guid>https://dev.to/matheusrich/til-javascripts-void-operator-58ni</guid>
      <description>&lt;p&gt;Today I discovered the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void#immediately_invoked_function_expressions" rel="noopener noreferrer"&gt;&lt;code&gt;void&lt;/code&gt;operator&lt;/a&gt; in JavaScript. It evaluates an expression but always returns &lt;code&gt;undefined&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// prints `undefined`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can be used on a &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/IIFE" rel="noopener noreferrer"&gt;IIFE&lt;/a&gt;, which usually uses parenthesis to make the function definition be interpreted as an expression and not a declaration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}();&lt;/span&gt;
&lt;span class="c1"&gt;// prints "hello world"&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;span class="c1"&gt;// prints "hello world"&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}();&lt;/span&gt;
&lt;span class="c1"&gt;// SyntaxError&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This operator is also useful to ensure that an arrow function always return &lt;code&gt;undefined&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// changes to the return value of `doSomething` won't affect this code&lt;/span&gt;
&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onclick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Caveat
&lt;/h2&gt;

&lt;p&gt;It’s important to note that this operator has a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table" rel="noopener noreferrer"&gt;high precedence&lt;/a&gt; with right-to-left associativity, so you may want to use parenthesis to correctly construct some expressions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// parsed as: (void "hello") + " world"&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; 'undefined world'&lt;/span&gt;

&lt;span class="k"&gt;void &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// parsed as: void ("hello" + " world")&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>todayilearned</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How To Get Pull Requests Merged Faster</title>
      <dc:creator>Matheus Richard</dc:creator>
      <pubDate>Thu, 25 Nov 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/matheusrich/how-to-get-pull-requests-merged-faster-2kg</link>
      <guid>https://dev.to/matheusrich/how-to-get-pull-requests-merged-faster-2kg</guid>
      <description>&lt;p&gt;No one likes huge Pull Requests. Reviewers have a hard time reading them, bugs sneak in, they took ages to get merged, conflicts pop everywhere… It’s a nightmare. There’s a better way to handle this.&lt;/p&gt;

&lt;p&gt;Listen carefully. It’s a secret: 🤫 &lt;em&gt;&lt;small&gt;make them small.&lt;/small&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“How do I do that?”&lt;/em&gt; - You may ask. To answer that, we have to learn about developer hats.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎩 Wearing one hat at a time
&lt;/h2&gt;

&lt;p&gt;Martin Fowler, in the &lt;a href="https://martinfowler.com/books/refactoring.html" rel="noopener noreferrer"&gt;Refactoring book&lt;/a&gt;, says that there are two types of software changes: behavioral and structural. Behavioral changes are when you add or remove features from the existing codebase, while structural changes are changes to the &lt;em&gt;code structure&lt;/em&gt; without changing any of its functionality. Those kinds of changes are fundamentally different, and we should avoid mixing them. Structural modifications are easily reversible, whereas behavioral often aren’t, for example.&lt;/p&gt;

&lt;p&gt;And &lt;strong&gt;that is the secret sauce for smaller PRs&lt;/strong&gt; : splitting those two kinds of changes whenever possible. In other words, separate refactoring from adding new features. It may seem small at first, but once we know the difference between those changes, we can start thinking a few steps ahead and plan how to work more efficiently.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Preparing the field&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Have you ever thought &lt;em&gt;“This change would be so simple if the code looked like X”&lt;/em&gt;?&lt;br&gt;
I have, and it’s often easier to add a new feature by refactoring the surroundings first.&lt;br&gt;
This technique is known as &lt;strong&gt;preparatory refactoring&lt;/strong&gt;&lt;br&gt;
Remember this classic quote:&lt;/p&gt;

&lt;center&gt;
“For each desired change, make the change easy (warning: this may be hard), then make the easy change” — Kent Beck
&lt;/center&gt;

&lt;p&gt;Before you start coding a new task, ask yourself: &lt;em&gt;“Would this be easier with some preparatory refactoring?”&lt;/em&gt;. The answer can make your work far easier.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another side effect you’ll see it’s that the code reviews themselves will improve. This happens because smaller code samples are easier to understand, so reviewers can focus deeper on what you did.&lt;/p&gt;

&lt;h2&gt;
  
  
  ➗ Dividing work
&lt;/h2&gt;

&lt;p&gt;Sometimes our workflow may lead to lots of files changed, and that’s okay. The thing is that &lt;strong&gt;we don’t need to add all of them to the same PR&lt;/strong&gt;. Once we got the work done, we can split commits into several &lt;a href="https://thoughtbot.com/blog/break-apart-your-features-into-full-stack-slices" rel="noopener noreferrer"&gt;deliverable&lt;/a&gt; PRs. Being &lt;a href="https://thoughtbot.com/blog/git-interactive-rebase-squash-amend-rewriting-history" rel="noopener noreferrer"&gt;comfortable with Git&lt;/a&gt; will make this task far more manageable.&lt;/p&gt;

&lt;h2&gt;
  
  
  💅 Nice presentation
&lt;/h2&gt;

&lt;p&gt;Stepping out from the code side a bit, if you want to make a good PR, make sure to make it appealing. Some file changes with no context at all won’t make a reviewer happy. Here are some things you can do to put a smile on their faces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Good description&lt;/strong&gt; : What is this PR doing? Is it a bugfix, a new feature, or refactoring? Does it include any breaking change?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context&lt;/strong&gt; : Please don’t just link a GitHub issue or a Jira ticket on your PRs. Try to answer some of these questions: &lt;em&gt;Why&lt;/em&gt; are you doing this? Why did you choose a particular approach? If possible, provide information (links, docs) to back it up. Benchmarks and screenshots are welcome as well.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good PR description makes the reviewer do less back-and-forth by proactively answering a lot of their questions in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Tests!
&lt;/h2&gt;

&lt;p&gt;Don’t forget to add tests to your code changes as well — unless it’s a refactoring, where the behavior stays the same. If you’re doing a bugfix, you &lt;a href="https://dev.to/a-simple-way-to-get-started-with-tdd/"&gt;already have the test scenarios&lt;/a&gt;; if you’re doing TDD, well, you already have the tests 😅. No matter how you prefer to work, tests add more confidence that the code works and prevents regressions in the future.&lt;/p&gt;

</description>
      <category>quicktip</category>
      <category>productivity</category>
      <category>codereview</category>
      <category>pullrequests</category>
    </item>
    <item>
      <title>Easy View Components In Jekyll</title>
      <dc:creator>Matheus Richard</dc:creator>
      <pubDate>Thu, 28 Oct 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/matheusrich/easy-view-components-in-jekyll-56na</link>
      <guid>https://dev.to/matheusrich/easy-view-components-in-jekyll-56na</guid>
      <description>&lt;p&gt;&lt;a href="https://jekyllrb.com/" rel="noopener noreferrer"&gt;Jekyll&lt;/a&gt; is a famous static site generator. It has over 43k stars on GitHub, but in our current &lt;a href="https://jamstack.org/what-is-jamstack/" rel="noopener noreferrer"&gt;JAMstack&lt;/a&gt; world, it’s not the shiniest star anymore.&lt;/p&gt;

&lt;p&gt;With web development becoming more complex — some would say _too_complicated—, Jekyll may feel bare bones when compared with competitor tools. One of the key aspects it lacks is components, which becomes a must with the introduction of &lt;a href="https://adamwathan.me/css-utility-classes-and-separation-of-concerns/" rel="noopener noreferrer"&gt;utility-first CSS&lt;/a&gt; libraries like &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I was losing hope, but then I discovered the &lt;a href="https://jekyllrb.com/docs/includes/" rel="noopener noreferrer"&gt;&lt;code&gt;include&lt;/code&gt;&lt;/a&gt; tag.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating components
&lt;/h2&gt;

&lt;p&gt;Include tags are kinda similar to partials in Rails: they allow us to include content from another file (stored in the &lt;code&gt;_includes&lt;/code&gt; directory).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;  &amp;lt;!-- This includes the contents of _includes/footer.html into this file --&amp;gt;
  &lt;span class="cp"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;footer.html&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cool thing is that you can pass parameters to include tags! This is where things start to get interesting. We can create components similar to what we would do with React, for example. But instead of using JS, we use &lt;a href="https://shopify.github.io/liquid/" rel="noopener noreferrer"&gt;Liquid&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;aside&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"max-w-md p-5 rounded bg-gray-50 border-l-4 border-l-blue-500"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;strong&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"block mb-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{include.title}}&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{include.content}}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/aside&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
Poorman's JSX





&lt;p&gt;And we use it in the template like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="cp"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;aside.html&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Include tags are cool"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Keep reading for caviats, tho"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s even possible to have parameters with default values using Liquid’s &lt;a href="https://shopify.github.io/liquid/filters/default/" rel="noopener noreferrer"&gt;&lt;code&gt;default&lt;/code&gt;&lt;/a&gt; filter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;aside&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"max-w-md p-5 rounded bg-gray-50 border-l-4 border-l-blue-500"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;strong&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"block mb-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{include.title | default: 'Note' }}&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- default value here --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{include.content}}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/aside&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Don’t be greedy!
&lt;/h2&gt;

&lt;p&gt;Include tags are powerful, but they add an overhead on the build time for your site, so don’t use them for &lt;em&gt;every single thing&lt;/em&gt;. The docs recommend not using them for every image on your blog, for example.&lt;/p&gt;

&lt;p&gt;A different approach would be using &lt;a href="https://jekyllrb.com/docs/plugins/tags/" rel="noopener noreferrer"&gt;custom Liquid tags&lt;/a&gt; to create components, but note that they are &lt;a href="https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/troubleshooting-jekyll-build-errors-for-github-pages-sites#unknown-tag-error" rel="noopener noreferrer"&gt;not supported&lt;/a&gt; by GitHub Pages — so automatic build/deploy won’t work.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;TIP: If you wanna something more… &lt;em&gt;modern (?)&lt;/em&gt; for doing JAMstack with Ruby, check out &lt;a href="https://bridgetownrb.com/" rel="noopener noreferrer"&gt;Bridgetown&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ruby</category>
      <category>ssg</category>
      <category>jekyll</category>
      <category>quicktip</category>
    </item>
    <item>
      <title>How Spaces Can Improve Your Code</title>
      <dc:creator>Matheus Richard</dc:creator>
      <pubDate>Tue, 31 Aug 2021 15:53:10 +0000</pubDate>
      <link>https://dev.to/matheusrich/how-spaces-can-improve-your-code-1e5d</link>
      <guid>https://dev.to/matheusrich/how-spaces-can-improve-your-code-1e5d</guid>
      <description>&lt;p&gt;Writing code is similar to writing an essay: it consists of many small parts that interact. One big giant blob of words is hard — and tedious — to read. To address this, we use paragraphs. The same technique can benefit our code. Here’s how.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logical blocks
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;A paragraph is a self-contained unit of discourse in writing dealing with a particular point or idea.&lt;em&gt;— Wikipedia&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The critical thing in this definition is “dealing with a particular point or idea”. Structuring our code with paragraphs (i.e., logical blocks) means we group related things and &lt;strong&gt;visually separate&lt;/strong&gt; them from the others. A simple new line makes a huge difference in readability. Let’s look at some examples to clarify this idea.&lt;/p&gt;

&lt;h3&gt;
  
  
  Separate test phases
&lt;/h3&gt;

&lt;p&gt;Consider this function: it takes two numbers and returns their sum. Pretty simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A possible unit test for this function could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[test]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;it_sums_two_numbers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this test follows the &lt;a href="https://thoughtbot.com/blog/four-phase-test" rel="noopener noreferrer"&gt;four-phase pattern&lt;/a&gt;, separating each test phase makes them more clear:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[test]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;it_sums_two_numbers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Grouping related concerns
&lt;/h3&gt;

&lt;p&gt;Programmers often use structures like modules and classes to tie code together. It is a great technique, but can lead to clutter if we’re not careful.&lt;/p&gt;

&lt;p&gt;Check out this Rails model. Even though it’s only a few lines long, it’s a bit hard to parse this class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Clearance&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;User&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:books&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:organization&lt;/span&gt;
  &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;presence: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
  &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;presence: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;uniqueness: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See how different it looks when we separate its logical blocks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Clearance&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;User&lt;/span&gt;

  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:books&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:organization&lt;/span&gt;

  &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;presence: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
  &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;presence: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;uniqueness: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we grouped each section by its “theme” (mixins, associations, validations, query methods, etc.). The spacing helps us see the logical separation between each section, which speeds us up when searching where to add and change code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Separate calculations from the return value
&lt;/h3&gt;

&lt;p&gt;Another great opportunity to use code blocks is in function bodies. We often do some preparation work before return the result, so it’s good to split those two parts up. This technique is especially beneficial when the language allows omitting the &lt;code&gt;return&lt;/code&gt; keyword.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;OBS: I’m omitting some details in this Rust implementation to keep it simpler.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;FileFormat&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;HTML&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;Latex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;Markdown&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;render_markdown_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;markdown_content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;format_to_convert_to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FileFormat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;format_to_convert_to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;FileFormat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;HTML&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;HTMLRenderer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nn"&gt;FileFormat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Latex&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;LatexRenderer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Cannot convert markdown to {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="nf"&gt;.render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;markdown_content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For those unfamiliar with Rust, omitting the semicolon in the last line indicates the function’s return value. It’s a subtle detail that is easy to miss. Adding a new line here makes it more evident where the calculations end and what is the actual return value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;render_markdown_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;markdown_content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;format_to_convert_to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FileFormat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Renderer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;format_to_convert_to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;FileFormat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;HTML&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;HTMLRenderer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nn"&gt;FileFormat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Latex&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;LatexRenderer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Cannot convert markdown to {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="nf"&gt;.render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;markdown_content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Extracting behavior
&lt;/h2&gt;

&lt;p&gt;Using logical blocks also helps us to refactor. It’s particularly useful to extract functionality: grouped lines probably will move together. Looking at the last example, we could extract the &lt;code&gt;match&lt;/code&gt; expression to its own function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;render_markdown_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;markdown_content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;format_to_convert_to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FileFormat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;renderer_for_format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;format_to_convert_to&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="nf"&gt;.render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;markdown_content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;renderer_for_format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FileFormat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Renderer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;FileFormat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;HTML&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;HTMLRenderer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
    &lt;span class="nn"&gt;FileFormat&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Latex&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;LatexRenderer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
    &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Cannot convert markdown to {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Simple but effective
&lt;/h2&gt;

&lt;p&gt;Separating logical blocks is a technique that is really simple but highly effective in making code more maintainable. Remember, we read code more than we write, so optimize your code for reading. A little effort today can save your team hours in the future.&lt;/p&gt;

</description>
      <category>code</category>
      <category>quicktip</category>
      <category>refactoring</category>
      <category>easy</category>
    </item>
    <item>
      <title>Kitchen Sink</title>
      <dc:creator>Matheus Richard</dc:creator>
      <pubDate>Thu, 22 Jul 2021 20:13:13 +0000</pubDate>
      <link>https://dev.to/matheusrich/kitchen-sink-1kn5</link>
      <guid>https://dev.to/matheusrich/kitchen-sink-1kn5</guid>
      <description>&lt;p&gt;Imagine you drink a glass of water and go to the kitchen sink to wash it. When you get there, there’s a HUGE pile of dirty dishes in the sink. To wash your glass, you would have to clean all the mess before. You look around… no one’s watching. You carefully put the glass in the sink’s corner and sneak out. You walk away thinking &lt;em&gt;“How things got this way?”&lt;/em&gt;. The ironic answer comes to your mind: &lt;em&gt;one glass a day&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In the same way, software accumulates technical debt over time. Most of the time, tech debt starts from simple actions:&lt;em&gt;“let’s add another method to that class”&lt;/em&gt;, &lt;em&gt;“let’s add another parameter to that function”&lt;/em&gt;, &lt;em&gt;“let’s duplicate that code for the 10th time… What? Don’t look at me, it’s how everyone does this!”&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Giant classes/functions/modules are like magnets: they attract all responsibilities to themselves and tend to get even bigger! There is so much code stuffed inside that everything seems to fit in there. That creates a sort of black hole that won’t stop growing.&lt;/p&gt;

&lt;p&gt;I’m not saying you should abstract early. I’m all aboard with &lt;a href="https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction" rel="noopener noreferrer"&gt;ma’am Sandi Metz&lt;/a&gt; on &lt;em&gt;“duplication is far cheaper than the wrong abstraction”&lt;/em&gt;, but an abstraction will &lt;em&gt;have&lt;/em&gt; to exist at some point.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚪 A way out
&lt;/h2&gt;

&lt;p&gt;If you thought &lt;em&gt;“I can’t touch this without breaking all the things”&lt;/em&gt;, you’re not the only one. Every developer will eventually deal with software that has technical debt and sometimes it may even seem that there’s no salvation. Luckily, smart folks like Martin Fowler taught us patterns for dealing with this very situation! The &lt;a href="https://martinfowler.com/bliki/StranglerFigApplication.html" rel="noopener noreferrer"&gt;Strangler Fig Pattern&lt;/a&gt;, for example, allows us to refactor big classes (or even applications) incrementally, without breaking backward compatibility!&lt;/p&gt;

&lt;p&gt;The point is, in the same way that there are &lt;a href="https://en.wikipedia.org/wiki/Software_design_pattern" rel="noopener noreferrer"&gt;design patterns&lt;/a&gt; for creating new code and addressing issues, there &lt;a href="https://martinfowler.com/books/refactoring.html" rel="noopener noreferrer"&gt;is a list of code smells and refactoring techniques&lt;/a&gt; to deal with them as well. Refactoring should be part of our daily work, not something &lt;em&gt;~special~&lt;/em&gt;. We should study, learn and teach others about it. The more we do it, the easier (and natural) it gets!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A refactor a day keeps the rewrite away!” - &lt;em&gt;Developer Granny&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🎸 Gravity is working against me
&lt;/h2&gt;

&lt;p&gt;Bad code attracts (more) bad code. Developers, especially when they’re new in a codebase, tend to repeat patterns. That way, expect a bad piece of code to influence similar instances. To prevent this &lt;strong&gt;we must resist inertia&lt;/strong&gt;. Yeah, it’s easy just to follow what everyone’s been doing, but this approach won’t work forever.&lt;/p&gt;

&lt;p&gt;How to do this? Following the &lt;a href="https://martinfowler.com/bliki/OpportunisticRefactoring.html" rel="noopener noreferrer"&gt;boy-scout rule&lt;/a&gt; &lt;em&gt;“always leave the code behind in a better state than you found it”&lt;/em&gt; helps to create a good mindset for it. We’ll think twice before just adding a new line of that huge method or nesting another &lt;code&gt;if/else&lt;/code&gt; statement. This rule helps us not to be afraid of taking small actions to improve the code. Did we touch a function? How can we improve it? Does it have tests? Can we &lt;a href="https://dev.to/matheusrich/don-t-use-comments-use-code-292o"&gt;use code to get rid of some comments&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;When we finally understand &lt;em&gt;that piece of spaghetti code&lt;/em&gt; (everyone has at least one in mind), we won’t keep it to ourselves! We have to materialize this knowledge in the code itself by renaming variables, functions, extracting small methods to clarify intention, etc. It costs us a bit today but will save a ton of time for other developers (or ourselves in 6 months).&lt;/p&gt;

&lt;p&gt;Those simple actions can be powerful in the long run! One glass a day, that dirty pile gets smaller. You may even have some partners joining this quest! Soon enough, that sink will be shining, and when it is clean, no one will want to be the first to leave a dirty dish there.&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>code</category>
    </item>
    <item>
      <title>My First Month (or so) With Rust</title>
      <dc:creator>Matheus Richard</dc:creator>
      <pubDate>Fri, 04 Jun 2021 11:00:00 +0000</pubDate>
      <link>https://dev.to/matheusrich/my-first-month-or-so-with-rust-5a92</link>
      <guid>https://dev.to/matheusrich/my-first-month-or-so-with-rust-5a92</guid>
      <description>&lt;p&gt;I’m learning Rust and this is the first post about my experience with it. I’m a Ruby programmer, so you may wanna check out &lt;a href="https://dev.to/on-learning-rust/"&gt;my post about the decision of learning Rust&lt;/a&gt; for more background.&lt;/p&gt;

&lt;p&gt;I delayed this post a lot because I didn’t do a lot of Rust in my first month. I had several things going on in my life, so I couldn’t focus on Rust as much as I would like. Anyway, I know that I have to put on paper some of my impressions before I forget them, so here I am.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔧 Setting up
&lt;/h2&gt;

&lt;p&gt;Setting up Rust was very easy: &lt;code&gt;rustup&lt;/code&gt; makes everything pretty straightforward, so I had no problems here. &lt;code&gt;Cargo&lt;/code&gt; is also very good, and I had no problems installing libraries (crates) too! Well done, Rust!&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Reading
&lt;/h2&gt;

&lt;p&gt;As I didn’t have much time to actually &lt;em&gt;code&lt;/em&gt; Rust, I spent a lot of time &lt;em&gt;reading&lt;/em&gt; about it. Regarding this, Rust is the language with &lt;strong&gt;best learning tools I’ve seen&lt;/strong&gt; to this day! Not only it has &lt;a href="https://doc.rust-lang.org/book/" rel="noopener noreferrer"&gt;a book&lt;/a&gt; (&lt;em&gt;The&lt;/em&gt; Book, I must say 😅) that guides you in the first steps to know the language and its unique features, but Rust also has a &lt;a href="https://doc.rust-lang.org/rust-by-example/" rel="noopener noreferrer"&gt;Learn by Example&lt;/a&gt; book!&lt;/p&gt;

&lt;p&gt;I think that this is a very nice pairing and both books are awesome in their way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Wanna start from scratch and learn about a concept?&lt;/strong&gt; Check out &lt;a href="https://doc.rust-lang.org/book/" rel="noopener noreferrer"&gt;The Book&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Just want to know the syntax for creating an anonymous function?&lt;/strong&gt; Here’s a book &lt;a href="https://doc.rust-lang.org/rust-by-example/fn/closures.html" rel="noopener noreferrer"&gt;full of examples&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Chapter 04 (the one about Ownership) of The Book was especially great for me. My mind was blown after reading it. Not because it was hard to read, but because everything made SO MUCH sense! All the pain points in C++ seemed to be solved with this ✨&lt;em&gt;magical&lt;/em&gt;✨ compiler. Well, that was in theory, let’s see how I did in practice, tho.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✍️ Writing
&lt;/h2&gt;

&lt;p&gt;I know that I should pick a simple topic to get me started when learning a new language, but I can’t control my desire to &lt;em&gt;create things&lt;/em&gt;. I don’t like to create &lt;em&gt;build-and-throw-away&lt;/em&gt; things, either. They should be useful things (at least to me)! So, to learn Rust I &lt;a href="https://github.com/MatheusRich/lambda-lang" rel="noopener noreferrer"&gt;started building an interpreter&lt;/a&gt; following &lt;a href="http://lisperator.net/pltut/" rel="noopener noreferrer"&gt;Lisperator.net’s tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To be honest, my first 100 lines of Rust were the basic algorithms in Chapters 01 and 02 of The Book, just to test out my setup and get to know a bit of the syntax. Four-space tabs and semicolons everywhere were kinda weird for me, but at least Rust doesn’t require explicit returns (and can avoid semicolons in the last expression too). &lt;code&gt;rustfmt&lt;/code&gt; was a neat addition, since I don’t have to care about how my code should be indented. 👍 for Rust here too!&lt;/p&gt;

&lt;p&gt;I was looking for things that were different in Rust and Ruby. Here are some examples of what I found:&lt;/p&gt;

&lt;h3&gt;
  
  
  🔢 Underscores and numbers
&lt;/h3&gt;

&lt;p&gt;Rust, like Ruby, allows underscores to separate numbers. The difference is that Rust allows multiple underscores (you can even have trailing ones):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Both examples work like a charm in Rust&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1_____2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// SyntaxError in Ruby: trailing `_' in number&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1_&lt;/span&gt;

&lt;span class="c1"&gt;// SyntaxError too&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1_____2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ❓ Rust has no ternary operator
&lt;/h3&gt;

&lt;p&gt;We can use &lt;code&gt;if/else&lt;/code&gt; expressions — which I’m very familiar with, coming from Ruby —, so I didn’t care not having it in Rust.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffuhsgkyilqlky2lqie69.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffuhsgkyilqlky2lqie69.png" alt="Gimme ternary or die!" width="697" height="174"&gt;&lt;/a&gt;Although this feature may be &lt;span&gt;very valuable&lt;/span&gt; for some users...&lt;/p&gt;

&lt;h3&gt;
  
  
  📏 Ranges are not inclusive
&lt;/h3&gt;

&lt;p&gt;To &lt;em&gt;me&lt;/em&gt; this was weird because it’s not the same I’m used to in Ruby.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ranges in Rust:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.count&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 9&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Ranges in Ruby:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; 10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I guess I’ll do some off-by-one errors until getting used to this. I found out later that there’s an inclusive version of ranges too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.count&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All in all, it was not &lt;em&gt;that&lt;/em&gt; different from Ruby. Yeah, Rust is a “curly braces language”, but with things like &lt;code&gt;enums&lt;/code&gt; and &lt;code&gt;impl&lt;/code&gt;, I could translate my OOP code fairly well. The &lt;a href="https://stevedonovan.github.io/rust-gentle-intro/object-orientation.html" rel="noopener noreferrer"&gt;Gentle Introduction To Rust&lt;/a&gt; chapter on OOP was particularly helpful for that.&lt;/p&gt;

&lt;p&gt;The main difference from Ruby for me was that in Rust I feel like I have to think about memory usage in &lt;strong&gt;each&lt;/strong&gt; line of code I write.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Learning by error
&lt;/h3&gt;

&lt;p&gt;Generally, Rust gave me really good compiler error messages. The fact I can run &lt;code&gt;rustc --explain SOME_ERROR&lt;/code&gt; and see details for this error makes learning Rust (without leaving the terminal) much easier.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://doc.rust-lang.org/std/index.html" rel="noopener noreferrer"&gt;stdlib documentation&lt;/a&gt; seems thorough and very modern: it has links for return types, traits, enums, tips, and examples.&lt;/p&gt;

&lt;h3&gt;
  
  
  🤝 The compiler is my friend
&lt;/h3&gt;

&lt;p&gt;After a long time writing in an interpreted dynamic typed language like Ruby, Rust’s compiler was a breath of fresh air. It’s &lt;strong&gt;so good&lt;/strong&gt; to know that I got a type checker having my back when I screw things up. I feel like I have to write fewer tests but still have the feeling that everything is working.&lt;/p&gt;

&lt;p&gt;Another difference is the lack of &lt;code&gt;null&lt;/code&gt; values 🙌. This is one of my favorite choices in Rust comparing to C++. Option types are much better IMO and having pattern matching makes dealing with them quite easy. About that, some constructors were &lt;strong&gt;really well&lt;/strong&gt; thought out, like: &lt;code&gt;enums&lt;/code&gt;, &lt;code&gt;if let&lt;/code&gt;,&lt;code&gt;while let&lt;/code&gt;. They are cohesive and fit the language like a glove.&lt;/p&gt;

&lt;h3&gt;
  
  
  🦀 Rusty Code
&lt;/h3&gt;

&lt;p&gt;It’s funny to learn a new language because I can’t tell what is idiomatic or not yet. For example, while coding my interpreter, I created the following function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;is_punctuation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;char&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;",;(){}[]"&lt;/span&gt;&lt;span class="nf"&gt;.contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I used &lt;code&gt;clone&lt;/code&gt; to satisfy the compiler, but I had the feeling that it was unnecessary. Later I ended up refactoring it to this version (which I &lt;em&gt;think&lt;/em&gt; is better):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;is_punctuation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;char&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;",;(){}[]"&lt;/span&gt;&lt;span class="nf"&gt;.contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don’t know if having the string inside the function is a good idea or if I should extract it into a constant or something. And that kind of question happened a lot:&lt;/p&gt;

&lt;h3&gt;
  
  
  🤔 A lot of questions
&lt;/h3&gt;

&lt;p&gt;As a beginner, I don’t know what are the best practices and idioms in Rust, so I had a lot of questions to ask. I had some classic beginner stuff like how to work with &lt;code&gt;modules&lt;/code&gt; and the &lt;code&gt;String&lt;/code&gt; vs &lt;code&gt;str&lt;/code&gt; vs &lt;code&gt;&amp;amp;str&lt;/code&gt; dilemma (which &lt;a href="https://www.brandons.me/blog/why-rust-strings-seem-hard" rel="noopener noreferrer"&gt;this blog post&lt;/a&gt; and my rustacean friend&lt;a href="http://github.com/pothix" rel="noopener noreferrer"&gt;@PotHix&lt;/a&gt; helped me to understand), and I’m expecting to have even more questions about memory management and that kind of stuff.&lt;/p&gt;

&lt;p&gt;I also don’t know when to move and when to borrow values, so I’m defaulting to borrow all the things and cloning defensively.&lt;/p&gt;

&lt;p&gt;I just found out &lt;a href="https://github.com/rust-lang/rust-clippy" rel="noopener noreferrer"&gt;📎 Clippy&lt;/a&gt;, which I think is kinda like&lt;a href="https://rubocop.org/" rel="noopener noreferrer"&gt;👮‍♂️ Rubocop&lt;/a&gt; for Rust, so I hope it will help me to write better Rust code.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔮 Future
&lt;/h2&gt;

&lt;p&gt;I plan to keep writing my interpreter in Rust to learn more about this language. One thing I didn’t explore yet is testing. Since I’m a &lt;a href="https://dev.to/a-simple-way-to-get-started-with-tdd/"&gt;big fan of TDD&lt;/a&gt; I hope Rust has a good test support. I have an interest in digging a bit in game development with the &lt;a href="https://bevyengine.org/" rel="noopener noreferrer"&gt;Bevy game engine&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’ll also make a post comparing Rust with &lt;a href="https://crystal-lang.org/" rel="noopener noreferrer"&gt;Crystal&lt;/a&gt; showing my experience with both languages.&lt;/p&gt;

&lt;p&gt;Oh, and if you’re a rustacean, feel free to give me any advice or tip you think is useful! Bye 🦀!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>learninpublic</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Different Ways to Contribute to Open Source</title>
      <dc:creator>Matheus Richard</dc:creator>
      <pubDate>Mon, 31 May 2021 23:00:00 +0000</pubDate>
      <link>https://dev.to/matheusrich/different-ways-to-contribute-to-open-source-46nf</link>
      <guid>https://dev.to/matheusrich/different-ways-to-contribute-to-open-source-46nf</guid>
      <description>&lt;p&gt;OSS is a wonderful thing! I was so grateful for the OSS tools I used in my projects, that I started contributing to OSS as retribution! If you want to get started with OSS contributions, here are several ways to do it.&lt;/p&gt;

&lt;p&gt;In each section I’m going to present a topic, explain it, and link some Pull Request that I did in that “category” so you can take a look to get inspired/learn something.&lt;/p&gt;

&lt;h2&gt;
  
  
  🐛 Bugfixes
&lt;/h2&gt;

&lt;p&gt;If you fix a bug, maintainers will &lt;strong&gt;love&lt;/strong&gt; you. It can be a bug you found, or a issue tagged with a &lt;a href="https://github.com/search?q=label%3Abug&amp;amp;type=Issues" rel="noopener noreferrer"&gt;&lt;code&gt;bug&lt;/code&gt;&lt;/a&gt; label. It is a good opportunity to fix that 1px misaligned item that is bothering you since forever.&lt;/p&gt;

&lt;p&gt;Or maybe you tried something and it didn’t work quite well on your machine. If you figure out what went wrong, &lt;strong&gt;don’t keep it to yourself&lt;/strong&gt;! Open a PR!&lt;/p&gt;

&lt;p&gt;Some bug fixes I did:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/crystal-ameba/github-action/pull/9" rel="noopener noreferrer"&gt;Ameba GH Action - Prevent linter to run on external libraries code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/crystal-ameba/ameba/pull/151" rel="noopener noreferrer"&gt;Ameba - Handle duplicated files when running linter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✨ New features
&lt;/h2&gt;

&lt;p&gt;Do you wish that a library did X for you? Don’t expect maintainers will do it for you. Code it and submit a PR! Maybe you already have something in your codebase that could be pushed upstream. That is what happened with the following contributions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/rspec/rspec-core/pull/2778" rel="noopener noreferrer"&gt;RSpec - Allow ordering specs by modification time&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/brianmaierjr/long-haul/pull/78" rel="noopener noreferrer"&gt;Long Haul - Add support for disqus comments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ueberdosis/tiptap/pull/213" rel="noopener noreferrer"&gt;tiptap - Add support to history custom settings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/codeodor/minitest-stub_any_instance/pull/13/files" rel="noopener noreferrer"&gt;mintest-stub_any_instance - Allow stubbing without a value&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is one of the nicest things about open source: you can contribute back to projects that helped you! You may open an issue first, asking maintainers if they like your feature idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚡ Improve performance / Refactor code
&lt;/h2&gt;

&lt;p&gt;If you’re experienced in a language you probably know some patterns or methods that are more performant than others, i.e, they run faster and/or with less memory. For instance, in Ruby using &lt;code&gt;each + push&lt;/code&gt; &lt;a href="https://github.com/JuanitoFatas/fast-ruby#enumerableeach--push-vs-enumerablemap-code" rel="noopener noreferrer"&gt;is slower&lt;/a&gt; than using &lt;code&gt;map&lt;/code&gt;. This is an opportunity to find those patterns and replace them with the more performant alternatives. When you do this kind of contribution, don’t forget to add benchmarks to your PR to make it more compeling.&lt;/p&gt;

&lt;p&gt;You can do some refactoring too: deleting unused code, fixing deprecation notes/methods, untangling some nested &lt;code&gt;if/else&lt;/code&gt; with &lt;a href="https://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html" rel="noopener noreferrer"&gt;guard clauses&lt;/a&gt;, etc. Making the code easier to read is important to add new features and finding bugs in the future.&lt;/p&gt;

&lt;p&gt;Here’s some PRs I did for &lt;a href="https://rubyonrails.org/" rel="noopener noreferrer"&gt;Ruby on Rails&lt;/a&gt; in this category:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/rails/rails/pull/42054" rel="noopener noreferrer"&gt;Replace &lt;code&gt;gsub&lt;/code&gt; with &lt;code&gt;tr&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rails/rails/pull/42053" rel="noopener noreferrer"&gt;Replace &lt;code&gt;map + compact&lt;/code&gt; with &lt;code&gt;filter_map&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rails/rails/pull/41335" rel="noopener noreferrer"&gt;Reduce memory allocations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧪 Add tests
&lt;/h2&gt;

&lt;p&gt;Tests make us feel more confident about the code we write and the changes we make. Well tested OSS benefits everyone using it! So, you can help yourself and the whole community by adding tests to a project! Adding a test coverage tool is another way to contribute in this topic. Setting up a coverage tool helps to understand which areas of the core aren’t tested.&lt;/p&gt;

&lt;p&gt;This was exactly what I did for &lt;code&gt;gem-web&lt;/code&gt;. I added &lt;a href="https://github.com/simplecov-ruby/simplecov" rel="noopener noreferrer"&gt;simplecov&lt;/a&gt; and with the coverage tool properly configured, I added tests for the missing parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/bitboxer/gem-web/pull/5" rel="noopener noreferrer"&gt;gem-web - Add test coverage tool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/bitboxer/gem-web/pull/6" rel="noopener noreferrer"&gt;gem-web - Add tests&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🐋 DevOps
&lt;/h2&gt;

&lt;p&gt;Adding a Docker/Docker Compose setup is a nice way to help newcomers onboard a project, especially when the project is an app with several moving parts (core, database, cache services etc). Setting up all that may be hard, but running &lt;code&gt;docker-compose up&lt;/code&gt; is &lt;em&gt;far&lt;/em&gt; easier.&lt;/p&gt;

&lt;p&gt;There’s other things you can contribute: almost every project nowadays has a Continuous Integration (CI) pipeline (Gitlab CI, GitHub Actions, Travis CI, Circle CI, Jenkins etc). Setting up a pipeline is an contribution in itself, but you can go further and set up linters, security checks and even a staging build in some cases!&lt;/p&gt;

&lt;p&gt;Here’s an example of a PR where I introduced a Dockerfile as an alternative setup build script:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/zynaddsubfx/zyn-fusion-build/pull/29" rel="noopener noreferrer"&gt;zynaddsubfx - Add Dockerfile&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  👩‍💻 OSS is more than code!
&lt;/h2&gt;

&lt;p&gt;As developers we love to code, but OSS is far beyond just coding! Maintainers have to deal with a variety of different problems: documentation, helping beginners, handling poor written issues, spams, reviewing Pull Requests, etc. We can do OSS by helping them with these tasks!&lt;/p&gt;

&lt;h3&gt;
  
  
  👍 Reviewing PRs
&lt;/h3&gt;

&lt;p&gt;You don’t need to be a maintainer to do that! I took much time to understand this. Reviewing PRs also helps the contributor to not feel bad about their work not being reviewed for many days, and you help address issues faster (typos, changing naming, refactorings, adding docs, etc). Just &lt;strong&gt;be kind&lt;/strong&gt; and helpful. Here’s &lt;a href="https://dev.to/sarajchipps/how-to-make-good-code-reviews-better-4ei-temp-slug-4012123"&gt;more tips on good code reviews&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🕵️‍♂️ Reproducing issues
&lt;/h3&gt;

&lt;p&gt;If you’ve been part of a reasonably used OSS project, then you know how hard is to handle issues. Many of them don’t even have enough information to reproduce and diagnose its causes. You can help maintainers by trying to reproduce issues! You may have to ask users for more information (OS, language, library versions, for example), or steps to reproduce it. Sometimes the behavior is not a problem, but a deliberate choice.&lt;/p&gt;

&lt;h3&gt;
  
  
  📝 Improving documentation
&lt;/h3&gt;

&lt;p&gt;This is one of my preferred ways to contributo to OSS. Here we have a lot of options: fixing typos, rewriting confusing sections, adding docs where it’s missing. The best is that you can improve documentation as you read it! If you’re learning a new tool, this may be the simplest way to start contributing!&lt;/p&gt;

&lt;p&gt;The contributions bellow were made just as I started studying the tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/luckyframework/website/pull/305" rel="noopener noreferrer"&gt;Lucky - Fix long links in small screens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/crystal-lang/crystal-book/pull/394" rel="noopener noreferrer"&gt;Crystal Book - Use simpler algorithm in docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amberframework/amber/pull/1153" rel="noopener noreferrer"&gt;Amber - Fix broken links in README&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🎨 Use your imagination!
&lt;/h3&gt;

&lt;p&gt;As I said earlier, OSS is not only about code! Any skill you have may be useful to someone! If you’re a musician or artist, for example, there’s plenty of things you can contribute to. Here’s an example of a PR where I created a logo for a project of a friend of mine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/andre-filho/commit-helper/pull/27" rel="noopener noreferrer"&gt;Commit Helper - Add logo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎯 General advices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Read contributing guide and code of conduct&lt;/strong&gt; This should be your first step before actually doing some contribution. Reading those guidelines will help you understand what contribution are accepted, how to make them, and what is necessary for approving them. Those are generally the files CONTRIBUTING.md and CODE_OF_CONDUCT.md;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Be patient and kind:&lt;/strong&gt; Maintainers have lives too! Most of them make &lt;strong&gt;no money&lt;/strong&gt; from OSS, so please be patient if your PR takes a while until being reviewed/approved;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It’s not about you:&lt;/strong&gt; Do not take things personally! If someone adds a comment about your code, it’s just about your code, don’t be sad about it, but use it as an opportunity to learn something;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not everything you do will/needs to be approved:&lt;/strong&gt; Sometimes our contributions don’t match the projects needs/vision and end up not accepted, and &lt;strong&gt;that’s okay&lt;/strong&gt;. This is part of open source and we have to understand it. The code you wrote can always live as a plugin/extension too. Here’s three unapproved PRs I did: 

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-lang/book/pull/2673" rel="noopener noreferrer"&gt;Rust Book - Improve example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kschiess/parslet/pull/200" rel="noopener noreferrer"&gt;Parslet - Convert README to markdown&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rubygems/rubygems/pull/2835" rel="noopener noreferrer"&gt;Rubygems - Add &lt;code&gt;web&lt;/code&gt; command&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  💪 Yes, you can
&lt;/h2&gt;

&lt;p&gt;First of all, contributing to open source is not a &lt;em&gt;experienced-developer-only&lt;/em&gt; thing. Many of the contributions I did were &lt;em&gt;because&lt;/em&gt; I was a beginner on the language/tool. &lt;strong&gt;Use this as your advantage&lt;/strong&gt; : beginners have sharp eyes for missing or confusing docs, for example. Your trajectory can help future beginners have a smoother onboarding!&lt;/p&gt;

&lt;p&gt;Look for issues with the tags &lt;a href="https://github.com/search?q=label%3Afirst-timers-only&amp;amp;type=Issues" rel="noopener noreferrer"&gt;first-timers-only-issue&lt;/a&gt;, &lt;a href="https://github.com/search?q=label%3Aeasy&amp;amp;type=Issues" rel="noopener noreferrer"&gt;easy&lt;/a&gt;, &lt;a href="https://github.com/search?q=label%3Abeginner&amp;amp;type=Issues" rel="noopener noreferrer"&gt;beginner&lt;/a&gt; and &lt;a href="https://github.com/search?q=label%3A%22good+first+issue%22&amp;amp;type=Issues" rel="noopener noreferrer"&gt;good first issue&lt;/a&gt;. And here’s a &lt;a href="https://github.com/MunGell/awesome-for-beginners" rel="noopener noreferrer"&gt;list of beginner-friendly projects&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now grab your cup of coffee, streach your hands and go do something awesome 😉!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Mocking Made Simple</title>
      <dc:creator>Matheus Richard</dc:creator>
      <pubDate>Thu, 22 Apr 2021 12:23:40 +0000</pubDate>
      <link>https://dev.to/matheusrich/mocking-made-simple-4191</link>
      <guid>https://dev.to/matheusrich/mocking-made-simple-4191</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TD;DR:&lt;/strong&gt; Inject dependencies instead of mocking functions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I was refactoring some React Native code the other day and ended up extracting the following function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/screen.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logScreenOpened&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;screenName&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;FirebaseLogger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logScreenView&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;screenName&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Could not log screen view. Error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I got to testing, I wanted to change the logger behavior in each test case, but I was struggling with &lt;a href="https://jestjs.io/docs/manual-mocks" rel="noopener noreferrer"&gt;Jest mocks&lt;/a&gt;. I wanted to do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// tests/screen-test.js&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;logScreenOpened&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;logs a screen view&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// TODO: mock logger's `logScreenView`&lt;/span&gt;

    &lt;span class="nf"&gt;logScreenOpened&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HomeScreen&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// TODO: expect logger to have received `logScreenView` with `{ screen: 'HomeScreen' }`&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;logs to console if logger raises an error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// TODO: mock logger's `logScreenView` to raise a error&lt;/span&gt;

    &lt;span class="nf"&gt;logScreenOpened&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// TODO: expect console to have received .error&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logScreenOpened&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;screenName&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;FirebaseLogger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logScreenView&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;screenName&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It was taking more time than I wanted to, so I gave up and came up with other solution. Not a fancy solution, neither changing the mocking library. It was, in fact, a very old one (and very known among Java devs): &lt;strong&gt;Dependency Injection&lt;/strong&gt; (DI for short).&lt;/p&gt;

&lt;h2&gt;
  
  
  Injecting dependencies
&lt;/h2&gt;

&lt;p&gt;So, instead of accessing &lt;code&gt;FirebaseLogger&lt;/code&gt; directly, we’ll provide it as an &lt;em&gt;argument&lt;/em&gt; of our function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/screen.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logScreenOpened&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screenName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;FirebaseLogger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logScreenView&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;screenName&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function is almost the same of the previous implementation, but receiving &lt;code&gt;logger&lt;/code&gt; as an argument gives us some flexibility.&lt;/p&gt;

&lt;p&gt;Here’s the thing: the &lt;code&gt;logScreenOpened&lt;/code&gt; function don’t need to know what &lt;code&gt;logger&lt;/code&gt; is. As long as it is an object that responds to &lt;code&gt;logScreenView&lt;/code&gt;, we’re good. That’s the only thing we care about. This is known as duck-typing (or interfaces).&lt;/p&gt;

&lt;p&gt;Back to testing: now we can change the logger implementation as we wish:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;logScreenOpened&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;logs a screen view&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logScreenViewMock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fakeLogger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;logScreenView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;logScreenViewMock&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nf"&gt;logScreenOpened&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HomeScreen&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fakeLogger&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;logScreenViewMock&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HomeScreen&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;logs to console if logger raises an error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logScreenViewMock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Some error!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nf"&gt;logScreenOpened&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fakeLogger&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Could not log screen view. Error: Some error!`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;OBS: We could’ve injected the &lt;code&gt;console.error&lt;/code&gt; bit too, but for this post I decided to keep things simple.&lt;/small&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Going ✨ fancy ✨
&lt;/h2&gt;

&lt;p&gt;We don’t have to always inject the dependency directly in our methods. We could go fancy and have a logging module that gives us different loggers depending on which environment we’re working on. Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// config/log.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;FirebaseLogger&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;firebase-logger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TestLogger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// simplified code to run in tests&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;TestLogger&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FirebaseLogger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in the app code we just import it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/screen.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;config/log&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logScreenOpened&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;screenName&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logScreenView&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;screenName&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Speeding up
&lt;/h2&gt;

&lt;p&gt;Refactors like this are nice when you want to to improve test performance too. Our fake logger is very lightweight, so those test are blazing fast! Use this to your advantage!&lt;/p&gt;

&lt;p&gt;Let’s say we have an function that does some heavy computation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;doStuff&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Lib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;veryHeavyComputation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;params&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;doMoreStuff&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We don’t want our tests to be slow, so let’s do the same thing here: inject dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;doStuff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lib&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Lib&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;lib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;veryHeavyComputation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;params&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;doMoreStuff&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, in our tests we swap the implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;doStuff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fastLib&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;veryHeavyComputation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()};&lt;/span&gt;

  &lt;span class="nf"&gt;doStuff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fastLib&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fastLib&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;params&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// other expectations&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have fast tests but guaranteeing the same API!&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap up
&lt;/h2&gt;

&lt;p&gt;Don’t be afraid of this kind of code! As I said, there’s nothing &lt;em&gt;new&lt;/em&gt; here. Is an old techniche used everywhere. In fact, &lt;a href="https://elixir-lang.org/" rel="noopener noreferrer"&gt;Elixir&lt;/a&gt;’s guides &lt;a href="https://elixirschool.com/en/lessons/basics/testing/#test-mocks" rel="noopener noreferrer"&gt;encourages this very approach&lt;/a&gt;! They call it “mock-as-a-noun” (in opposition of “mock-as-a-verb”).&lt;/p&gt;

&lt;p&gt;One think to keep in mind: &lt;strong&gt;we must keep the API of our fake logger in sync with the original one&lt;/strong&gt;. This is important because we don’t want our tests passing but our production code failing. So is it good to have a integration test covering the usage of that mock too!&lt;/p&gt;

&lt;p&gt;That’s it, happy mocking! &lt;small&gt;(wait, that’s a verb!)&lt;/small&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>refactoring</category>
      <category>mocks</category>
      <category>quicktip</category>
    </item>
    <item>
      <title>On learning Rust</title>
      <dc:creator>Matheus Richard</dc:creator>
      <pubDate>Sat, 27 Mar 2021 20:46:58 +0000</pubDate>
      <link>https://dev.to/matheusrich/on-learning-rust-51np</link>
      <guid>https://dev.to/matheusrich/on-learning-rust-51np</guid>
      <description>&lt;p&gt;As of March 26th of 2021, I decided to learn Rust. I’ve heard of it a couple of years ago but never had time (i.e. priority) to dig into it. Now it’s time to really understand what is it all about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I am starting
&lt;/h2&gt;

&lt;p&gt;I already know — or &lt;em&gt;think&lt;/em&gt; I know — some things about Rust. It is a systems language, but with a modern feel. That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It’s fast:&lt;/strong&gt; it wants to replace C/C++ for a reason;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It’s safe:&lt;/strong&gt; no &lt;code&gt;null&lt;/code&gt;s here;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It has a nice package manager:&lt;/strong&gt; no more vendoring dependencies;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It has something about memory management:&lt;/strong&gt; it seems almost like type-checking, but for memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those things really speak to me because I’ve spent the past 5 years or so doing Ruby. Don’t get me wrong, I &lt;strong&gt;love&lt;/strong&gt; Ruby. It’s my main language, I work with it every day (and in my side projects). It really fits my way of thinking and it’s my go-to tool. But, &lt;em&gt;because&lt;/em&gt; I know it so well, I know its flaws too.&lt;/p&gt;

&lt;p&gt;With that in mind, I wanted to have a “complementary” tool at my disposal. Instead of a dynamic-typed, scripting language, this time I need a statically-typed, fast, compiled language.&lt;/p&gt;

&lt;p&gt;I did some C/C++ in the past, but I feel like they’re stuck in the past. I know &lt;a href="https://crystal-lang.org/" rel="noopener noreferrer"&gt;Crystal&lt;/a&gt; and even started to &lt;a href="https://github.com/lit-lang/lit" rel="noopener noreferrer"&gt;build an interpreter&lt;/a&gt; with it. It was pretty easy to get started with it, due to its &lt;em&gt;huge&lt;/em&gt; similarity to Ruby. Unfortunately, the language is still in its infancy (but I have hope in its future). Thus, Rust became my choice.&lt;/p&gt;

&lt;p&gt;I worked a bit with functional languages like Haskell and Elm, so concepts like monads are no scary to me. I hope that this will make things easier for me in Rustland.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I am aiming for
&lt;/h2&gt;

&lt;p&gt;I have no intentions to work professionally with Rust (who knows, tho? 🤷), but I think it’s nice to have different (and complementary) tools. Now I don’t have performance-demanding requirements, but when I have — and that day &lt;em&gt;will&lt;/em&gt; eventually come — I want to be prepared. I may even use Rust in my current job.&lt;/p&gt;

&lt;p&gt;My main goal is to have a fast and safe systems language to build games and interpreters. Those are the only performance-heavy tasks that are fun to me (sorry machine learning). It’s important to stress this word: &lt;strong&gt;fun&lt;/strong&gt;. Learning a new language is a kind of investment, and I wanted it to be fun, so I don’t feel like I’m wasting my time.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I’ll do it
&lt;/h2&gt;

&lt;p&gt;Since I have no professional goals with Rust, my study will be guided by my curiosity. That’s the way I like to study things. I’ll read the docs, tutorials, make small programs and games just for fun.&lt;/p&gt;

&lt;p&gt;I won’t establish goals, or study ours. I have a full-time job, an undergraduate thesis to finish, and a family. This should be as fun as playing God of War on my PS4.&lt;/p&gt;

&lt;p&gt;I’ll document the process if I find something interesting to share (like differences between Rust and Ruby in my experience), or how one language influenced how I code on the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evaluating my results
&lt;/h2&gt;

&lt;p&gt;One year from now I’ll write another blog post about my journey. Maybe I’ll end up liking Rust very much, maybe not. Or maybe I’ll be lazy and not studying so much, after all. Anyway, if you’re reading this blog post after 2021, my impressions of one year doing Rust will be linked »here«.&lt;/p&gt;

&lt;p&gt;Cya, rustaceans.&lt;/p&gt;

</description>
      <category>rust</category>
    </item>
    <item>
      <title>Don't use comments! Use code.</title>
      <dc:creator>Matheus Richard</dc:creator>
      <pubDate>Fri, 26 Mar 2021 20:56:17 +0000</pubDate>
      <link>https://dev.to/matheusrich/don-t-use-comments-use-code-292o</link>
      <guid>https://dev.to/matheusrich/don-t-use-comments-use-code-292o</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Let’s get this straight: &lt;strong&gt;comments are a code smell&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Whenever I feel like adding comments to my code I stop and ask myself: &lt;em&gt;“Is there any way to NOT use comments here and use code instead?”&lt;/em&gt;. Often the answer is &lt;em&gt;“yes”&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Comments are a lazy solution for developers. They spare us from thinking about abstractions and naming (which is &lt;a href="https://martinfowler.com/bliki/TwoHardThings.html" rel="noopener noreferrer"&gt;one of the hardest things&lt;/a&gt; in Computer Science indeed), and that’s why they’re so tempting.&lt;/p&gt;

&lt;p&gt;However, we can easily avoid (most) comments! As the saying goes &lt;em&gt;“Talk is cheap, show me the code”&lt;/em&gt;. So, here we go:&lt;/p&gt;

&lt;h2&gt;
  
  
  Describing the obvious
&lt;/h2&gt;

&lt;p&gt;Let’s get this one out of the way: these “describing” comments are just useless. They’re just duplications and add no value. On the contrary, they encourage other developers to do the same! Just get rid of them. Good variable and function naming is the way to go here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;### DON'T ###&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Dungeon&lt;/span&gt;
  &lt;span class="c1"&gt;# Generates an array of rooms&lt;/span&gt;
 &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_arr&lt;/span&gt;
    &lt;span class="c1"&gt;# Initializes an empty array of rooms&lt;/span&gt;
    &lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="c1"&gt;# Creates five rooms with the given width and height and add them the `arr` variable&lt;/span&gt;
    &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;create_room&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# ...&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;### DO ###&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Dungeon&lt;/span&gt;
 &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_rooms&lt;/span&gt;
    &lt;span class="n"&gt;rooms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;rooms&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;create_room&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;width: &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;height: &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# ...&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Just do it
&lt;/h2&gt;

&lt;p&gt;Probably the most common use of comments: explaining what the code does. If we have the principle &lt;a href="https://martinfowler.com/bliki/TellDontAsk.html" rel="noopener noreferrer"&gt;“Tell, don’t ask”&lt;/a&gt; in OOP, for commenting it should be &lt;strong&gt;“Do, don’t tell”&lt;/strong&gt;. Extracting behavior into modules/functions makes searching, modifying, and testing far easier than when using comments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;### DON'T ###&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;something_important&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"stty -echo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# disables echo on terminal&lt;/span&gt;
  &lt;span class="n"&gt;read_password&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"stty echo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# enables echo on terminal&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;### DO ###&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Terminal&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enable_echo&lt;/span&gt;
    &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"stty echo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disable_echo&lt;/span&gt;
    &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"stty -echo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;something_important&lt;/span&gt;
  &lt;span class="no"&gt;Terminal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disable_echo&lt;/span&gt;
  &lt;span class="n"&gt;read_password&lt;/span&gt;
  &lt;span class="no"&gt;Terminal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enable_echo&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  No magic numbers!
&lt;/h2&gt;

&lt;p&gt;I’ll admit this: comments are a &lt;em&gt;bit&lt;/em&gt; better than &lt;strong&gt;nothing&lt;/strong&gt; in this case. But we can do better! Fixing those is pretty simple: add a constant. You can use a simple type like an integer, or get fancy with hash-tables, structs and objects if needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;### DON'T ###&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;notify&lt;/span&gt;
  &lt;span class="n"&gt;send_msg&lt;/span&gt; &lt;span class="s2"&gt;"Hello world!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;channel: &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# General&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;### DO ###&lt;/span&gt;

&lt;span class="no"&gt;GENERAL_CHANNEL_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;notify&lt;/span&gt;
  &lt;span class="n"&gt;send_slack_msg&lt;/span&gt; &lt;span class="s1"&gt;'Hello world!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;channel: &lt;/span&gt;&lt;span class="no"&gt;GENERAL_CHANNEL_ID&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;### DO² ###&lt;/span&gt;

&lt;span class="no"&gt;CHANNEL_IDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;OpenStruct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;general: &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;notify&lt;/span&gt;
  &lt;span class="n"&gt;send_slack_msg&lt;/span&gt; &lt;span class="s1"&gt;'Hello world!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;channel: &lt;/span&gt;&lt;span class="no"&gt;CHANNEL_IDS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;general&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Comments for measurement units
&lt;/h2&gt;

&lt;p&gt;Some people think this kind of comment is OK. I think, as in most of the cases, that a simple function replaces them. This is the kind of thing that spreads quickly throughout your code, but it’s easy to avoid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;### DON'T ###&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;RecurringJob&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;
    &lt;span class="n"&gt;do_important_stuff&lt;/span&gt;

    &lt;span class="n"&gt;seconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="c1"&gt;# 6 hours&lt;/span&gt;
    &lt;span class="no"&gt;RecurringJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;### DO ###&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Seconds&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_hours&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hours&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;hours&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;RecurringJob&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;
    &lt;span class="n"&gt;do_important_stuff&lt;/span&gt;

    &lt;span class="n"&gt;seconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Seconds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_hours&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;RecurringJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using a module like that opens the possibility for other conversions, like &lt;code&gt;from_minutes&lt;/code&gt;, &lt;code&gt;from_days&lt;/code&gt;, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don’t use comments to separate things
&lt;/h2&gt;

&lt;p&gt;If you’re using comments to divide a file into sections, this may indicate that this file does too much. It’s better to split it into several modules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;### DON'T ###&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Utils&lt;/span&gt;
  &lt;span class="c1"&gt;### File System ###&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;file_exists?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;### Text format ###&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;italic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;### DO ###&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Utils::FS&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;file_exists?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Utils::Format&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;italic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Don’t add TODO’s
&lt;/h2&gt;

&lt;p&gt;These kinds of TODO’s rarely get done. If you’re the one adding the comment, you’re the one that cares about it. Do it now!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;### DON'T ###&lt;/span&gt;

&lt;span class="c1"&gt;# TODO: handle exceptions&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="no"&gt;TwitterClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;### DO ###&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="no"&gt;TwitterClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;TwitterClient&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
  &lt;span class="n"&gt;log_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don’t have time to deal with it? &lt;strong&gt;Open an issue&lt;/strong&gt; instead. Issues are prioritized and end up in your development pipeline (or maybe in some OSS contributor’s). Those TODO comments will be forgotten as soon as your code goes to production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don’t add deprecation notes
&lt;/h2&gt;

&lt;p&gt;Deprecating code with comments is not efficient. Especially in libraries, developers won’t read source code before using it. Be proactive and do something actionable (like a warning) right away.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;### DON'T ###&lt;/span&gt;

&lt;span class="c1"&gt;# DEPRECATED: use `puts` instead&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;### DO ###&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;deprecate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alternative&lt;/span&gt;&lt;span class="p"&gt;:)&lt;/span&gt;
  &lt;span class="no"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"[DEPRECATION] `&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;` is deprecated. Use &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;alternative&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; instead."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;deprecate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:printf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;alternative: :puts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Are you using comments to generate deprecation documentation? Read this section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don’t add after-update notes
&lt;/h2&gt;

&lt;p&gt;This is the same principle as the one before: codify your comments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;### DON'T ###&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;BaseModel&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;without_author&lt;/span&gt;
    &lt;span class="c1"&gt;# TODO: Use Post.where.missing(:author) after Rails 6.1&lt;/span&gt;
    &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;left_joins&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:author&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;authors: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;id: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;### DO ###&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;BaseModel&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;without_author&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s1"&gt;'Use `Post.where.missing(:author)` instead'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;version&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="s1"&gt;'6.1'&lt;/span&gt;

    &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;left_joins&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:author&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;authors: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;id: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If an &lt;code&gt;exception&lt;/code&gt; is too harsh for you, you can just give a warning.&lt;/p&gt;

&lt;p&gt;You could go even further:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;### DO² ###&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;BaseModel&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;without_author&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;version&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="s1"&gt;'6.1'&lt;/span&gt;
      &lt;span class="no"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt; &lt;span class="s1"&gt;'Delete the else branch of this conditional'&lt;/span&gt;
      &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;missing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:author&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;left_joins&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:author&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;authors: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;id: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is especially useful if the new method is more performant than the older one. You’ll get instant performance without changing your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don’t use comments as backup
&lt;/h2&gt;

&lt;p&gt;Developers shouldn’t fear deleting code. Commented code just muddles everything around it. Do you think you may need it later? Short answer: &lt;em&gt;you probably won’t&lt;/em&gt;. And even if you do, that’s why we have Version Control Systems like Git &lt;small&gt;(If you’re not using a VCS, what are you doing?!)&lt;/small&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;### DON'T ###&lt;/span&gt;

&lt;span class="c1"&gt;# NOTE: Maybe I'll need this someday&lt;/span&gt;
&lt;span class="c1"&gt;# def my_algorithm&lt;/span&gt;
&lt;span class="c1"&gt;# old(implementation)&lt;/span&gt;
&lt;span class="c1"&gt;# end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;my_algorithm&lt;/span&gt;
  &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When comments are OK
&lt;/h2&gt;

&lt;p&gt;I’m not here to say that &lt;em&gt;every&lt;/em&gt; comment is bad. There are some cases when they’re the last resource. If &lt;em&gt;no code&lt;/em&gt; can do what you want, don’t be ashamed to add a comment. Some examples:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Comments as documentation
&lt;/h3&gt;

&lt;p&gt;Most languages have tools to generate documentation using code comments. That is nice because it keeps the docs near the code it refers to. Here’s an example of &lt;a href="https://yardoc.org/" rel="noopener noreferrer"&gt;YARD&lt;/a&gt;, a Ruby documentation tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Reverses the contents of a String or IO object.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# @param contents [String, #read] the contents to reverse&lt;/span&gt;
&lt;span class="c1"&gt;# @return [String] the contents reversed lexically&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond_to?&lt;/span&gt; &lt;span class="ss"&gt;:read&lt;/span&gt;
  &lt;span class="n"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reverse&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Comments as code (wut?)
&lt;/h3&gt;

&lt;p&gt;Sometimes comments are &lt;em&gt;actually&lt;/em&gt; code. That is, they can be used to produce some behavior.&lt;/p&gt;

&lt;h4&gt;
  
  
  Magic comments
&lt;/h4&gt;

&lt;p&gt;Ruby has &lt;a href="https://docs.ruby-lang.org/en/3.0.0/doc/syntax/comments_rdoc.html#label-Magic+Comments" rel="noopener noreferrer"&gt;magic comments&lt;/a&gt; that change the behavior of the interpreter in some ways. Just put them in the beginning of the file, and it will take effect. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This comment makes the interpreter warns about wrong indentation:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# warn_indent: true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;You can change the file’s encoding:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# encoding: utf-8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Parsing comments
&lt;/h4&gt;

&lt;p&gt;Some libraries parse comments too. Linters often use comments to disable rules momentarily:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# rubocop:disable Layout/LineLength&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;this_could_be_a_very_long_line_that_extends_forever_into_infinity&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# rubocop:enable Layout/LineLength&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another example is the library &lt;a href="https://dev.to/matheusrich/baking-tasks-with-bake-4ki9"&gt;Bake&lt;/a&gt;, which parses documentation comments to get information about type coercions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Creates a new post&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# @param post_name [String] name of the post to be created.&lt;/span&gt;
&lt;span class="c1"&gt;# @param categories [Array(Symbol)] categories of the post.&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;new_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;categories: &lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
  &lt;span class="n"&gt;pp&lt;/span&gt; &lt;span class="n"&gt;categories&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way it parses input from the terminal and automatically coerces params into the desired type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bake new_post &lt;span class="s1"&gt;'test-post'&lt;/span&gt; &lt;span class="nv"&gt;categories&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ruby,testing
&lt;span class="c"&gt;# output: [:ruby, :testing]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OBS: even though type checking &lt;em&gt;can&lt;/em&gt; be implemented with comments, &lt;a href="https://dev.to/scottw/sorbet-5fdf-temp-slug-1554971"&gt;sorbet&lt;/a&gt;, &lt;a href="https://github.com/ruby/rbs" rel="noopener noreferrer"&gt;rbs&lt;/a&gt;, and &lt;a href="https://www.ruby-toolbox.com/search?display=compact&amp;amp;q=type+check" rel="noopener noreferrer"&gt;several others&lt;/a&gt; have shown that type checking dynamic-typed languages is possible with code.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. When you have no other tool
&lt;/h3&gt;

&lt;p&gt;Sometimes there are some things that you cannot explain with code. I’m not talking about how you did, but &lt;em&gt;why&lt;/em&gt; you did them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_foos&lt;/span&gt;
  &lt;span class="c1"&gt;# NOTE: We're disabling params sorting because the FooAPI requires&lt;/span&gt;
  &lt;span class="c1"&gt;# params to be in the following order: foo, bar, baz&lt;/span&gt;
  &lt;span class="no"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/foo-api'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;params: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;foo: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;bar: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;baz: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="ss"&gt;sort_params: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you have any other good cases for comments? Let me know in the comments!&lt;/p&gt;

&lt;h2&gt;
  
  
  Comments are not code!
&lt;/h2&gt;

&lt;p&gt;Comments tend to get lost and collect dust. When we’re in a big refactor, we’ll rarely think in refactoring comments too. Comments &lt;em&gt;are not tested&lt;/em&gt;, so they end up outdated, with typos, wrong information, and worse: &lt;strong&gt;bugs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Using code, on the other hand, has several benefits: syntax highlighting, grepping, compile/runtime checks, &lt;em&gt;testing&lt;/em&gt;!&lt;/p&gt;

&lt;p&gt;Comments are a confession that we were unable to represent our ideas with code. That happens sometimes, but try your best to avoid them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TLDL:&lt;/strong&gt; Don’t use comments. Codify your comments.&lt;/p&gt;

</description>
      <category>code</category>
      <category>refactoring</category>
      <category>comments</category>
    </item>
    <item>
      <title>Productive Laziness</title>
      <dc:creator>Matheus Richard</dc:creator>
      <pubDate>Wed, 24 Feb 2021 13:57:55 +0000</pubDate>
      <link>https://dev.to/matheusrich/productive-laziness-40no</link>
      <guid>https://dev.to/matheusrich/productive-laziness-40no</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;You’re tired. Exhausted. Your mind simply isn’t responding. You stare at the code; it stares back at you. You type something. It doesn’t work. You delete it. The clock says: &lt;code&gt;04:00 PM&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
You know what you need: &lt;strong&gt;a break&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Working when we’re tired is &lt;strong&gt;really dangerous&lt;/strong&gt; (to us and our applications). We write buggy code, make silly mistakes, they frustrate us, and, finally, &lt;em&gt;we burn out&lt;/em&gt;. Everyone has been there. So, what to do rather than keep hammering your head on the keyboard?&lt;/p&gt;

&lt;p&gt;In fact, you got a lot of options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lie down (or get up if you’ve been sitting for a long time);&lt;/li&gt;
&lt;li&gt;Change the room you’re working on;&lt;/li&gt;
&lt;li&gt;Take a shower;&lt;/li&gt;
&lt;li&gt;Take a (short) nap;&lt;/li&gt;
&lt;li&gt;Go on a walk (&lt;em&gt;to your backyard&lt;/em&gt; 😢) and look at the sky;&lt;/li&gt;
&lt;li&gt;Play a song on your guitar;&lt;/li&gt;
&lt;li&gt;Play with your pet;&lt;/li&gt;
&lt;li&gt;Tell your loved ones you love them;&lt;/li&gt;
&lt;li&gt;At least go drink some water! You get hydrated and &lt;a href="https://arthur.ludus.club/en/hacking/productivity/2020/02/02/habit-drink-water.html" rel="noopener noreferrer"&gt;it may boost your productivity!&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important part is to get some distance from the problem you’re facing. &lt;strong&gt;Context switch is really important&lt;/strong&gt;. You may think that breaks will kill your flow, and it’s easy to convince yourself that you don’t have time for them, but hear me out: &lt;strong&gt;they work!&lt;/strong&gt; Well, you don’t have to trust me,  &lt;a href="https://thewellbeingthesis.org.uk/foundations-for-success/importance-of-taking-breaks-and-having-other-interests/#:~:text=Taking%20breaks%20has%20been%20shown,and%20cardiovascular%20disease%20%5B2%5D." rel="noopener noreferrer"&gt;science has shown this over and over again&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  I can’t take a nap! I’m working!
&lt;/h2&gt;

&lt;p&gt;I realize not everyone has the freedom/opportunity to do those things. Or you may not be comfortable doing them during work time, and I get it. So, I’ll list some alternative tasks you can do instead. I call them &lt;em&gt;productive laziness&lt;/em&gt; because even though they’re not your primary task, they’re still useful (for you and your app)!&lt;/p&gt;

&lt;h3&gt;
  
  
  Productive laziness tasks
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Review Pull Requests from libraries you like
&lt;/h4&gt;

&lt;p&gt;You don’t need to be a maintainer to do this! OSS folks have &lt;em&gt;lots of work&lt;/em&gt; to do, so go ahead and give them some help (and maybe you &lt;em&gt;do&lt;/em&gt; end up as a maintainer). You don’t need to be an expert in the project. Just knowing the programming language behind it can help you! You can suggest better variable/method names or methods with better performance, for instance. But please, &lt;strong&gt;be kind&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Open Pull Requests for libraries you like
&lt;/h4&gt;

&lt;p&gt;If you’re feeling brave, you can help OSS ever further! Fix some bug reported into their issue tracker. Maybe a refactor or performance improvement? Search for issues with tags like&lt;code&gt;good-first-issue&lt;/code&gt;, &lt;code&gt;easy&lt;/code&gt;, &lt;code&gt;beginner&lt;/code&gt; or &lt;code&gt;first-time-contributor&lt;/code&gt;. That’s how I got my &lt;a href="https://github.com/rails/rails/pull/41335" rel="noopener noreferrer"&gt;first contribution merged into Rails&lt;/a&gt;!&lt;/p&gt;

&lt;h4&gt;
  
  
  Read docs from languages/libraries you use
&lt;/h4&gt;

&lt;p&gt;This is quite obvious, but learning that one method can save your life later! You may found a new helper method that makes your code simpler or faster.&lt;/p&gt;

&lt;h4&gt;
  
  
  Read a blog post
&lt;/h4&gt;

&lt;p&gt;This is basically the same as the previous one, but it doesn’t have to be technical. You can learn some productivity technique, read something inspiring or just laugh out loud. I’m pretty sure you have some marked as “read later” somewhere.&lt;/p&gt;

&lt;h4&gt;
  
  
  Write a blog post
&lt;/h4&gt;

&lt;p&gt;I’m pretty sure you have something to tell. Don’t worry, you don’t have to finish it right away. Just put some basic ideas in the paper. You’ll perfect it later.&lt;/p&gt;

&lt;h4&gt;
  
  
  Learn some keybindings on your text editor
&lt;/h4&gt;

&lt;p&gt;Consider this an investment: a couple of minutes today saves you a life of keystrokes! You can learn some terminal tricks too! It is the same idea.&lt;/p&gt;

&lt;h4&gt;
  
  
  Reply that one email you’ve been postponing
&lt;/h4&gt;

&lt;p&gt;It’ll only take you 5 minutes. Get rid of it accumulating dust in your mailbox and in your brain.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pay off some technical debt
&lt;/h4&gt;

&lt;p&gt;This is &lt;em&gt;by far&lt;/em&gt; my favorite alternative task. Here you can do what you like the most:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fix &lt;a href="https://stackoverflow.com/questions/97197/what-is-the-n1-selects-problem-in-orm-object-relational-mapping" rel="noopener noreferrer"&gt;N+1 queries&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;Add tests to improve your test coverage;&lt;/li&gt;
&lt;li&gt;Improve the loading time for some page in your web app (using lighthouse and other dev tools);&lt;/li&gt;
&lt;li&gt;Fix that one exception that your monitoring tool reported. This might be a good opportunity to start TDDing. &lt;a href="https://dev.to/a-simple-way-to-get-started-with-tdd/"&gt;Here’s how&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Solve some simple CSS problem: alignments or spacing issues, for example;&lt;/li&gt;
&lt;li&gt;Refactor some nasty code you find. You can do simple things like renaming variables/methods or extracting functions/classes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A refactor a day keeps the rewrite away!” - &lt;em&gt;Developer Granny&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You may not fix that nasty bug by the end of the day, but a least &lt;em&gt;your app will be faster/cleaner/have more tests&lt;/em&gt;! I think that’s a nice trade-off.&lt;/p&gt;

&lt;h3&gt;
  
  
  It’s all about incentives!
&lt;/h3&gt;

&lt;p&gt;These short tasks give us small wins, and they motivates us to keep working on annoying chores.&lt;/p&gt;

&lt;p&gt;Here’s something to keep an eye on: be sure to &lt;strong&gt;make the laziness time-boxed&lt;/strong&gt;! You don’t want to spend the whole day in a alternative task 😜.&lt;/p&gt;

&lt;p&gt;Finally, no matter how your day goes, be kind to yourself. Some days are amazing, some days are terrible, but most days are just doing the work of life. Do your best to enjoy them!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>A Simple Way To Get Started With TDD</title>
      <dc:creator>Matheus Richard</dc:creator>
      <pubDate>Mon, 18 Jan 2021 13:49:33 +0000</pubDate>
      <link>https://dev.to/matheusrich/a-simple-way-to-get-started-with-tdd-3h6b</link>
      <guid>https://dev.to/matheusrich/a-simple-way-to-get-started-with-tdd-3h6b</guid>
      <description>&lt;p&gt;TDD is &lt;strong&gt;awesome&lt;/strong&gt; , but also confusing (and even scary) for those who never practiced it. But it doesn’t have to! We’re gonna learn how to get started with it by &lt;strong&gt;fixing bugs&lt;/strong&gt; (so we can kill two birds with one stone).&lt;/p&gt;

&lt;p&gt;» If 3 min is too long, here’s the TL;DL&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;em&gt;OBS: the code snippets are below are in ruby, but the core concept applies to any language.&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Oh, no! You got a bug in production!
&lt;/h2&gt;

&lt;p&gt;Your monitoring tool is screaming at you the famous &lt;a href="https://en.wikipedia.org/wiki/Null_pointer#History:~:text=History,-%5B" rel="noopener noreferrer"&gt;Billion Dollar Mistake&lt;/a&gt;: &lt;code&gt;NoMethodError: undefined method 'split' for nil:NilClass&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You look at the logs a see where this exception raised:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NoMethodError: undefined method `empty?' for nil:NilClass
your_app/models/user.rb:2:in `invalid?'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Something went wrong with that User model. Let’s check its code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;BaseModel&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;invalid?&lt;/span&gt;
    &lt;span class="vi"&gt;@name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;-- The error occurred here&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save!&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s1"&gt;'Cannot save invalid user!'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;invalid?&lt;/span&gt;

    &lt;span class="ss"&gt;:saved_on_db&lt;/span&gt; &lt;span class="c1"&gt;# I'm simplifying the record creation on DB here&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, before saving the user, it had a &lt;code&gt;nil&lt;/code&gt; name. We have a validation, but it only checks if &lt;code&gt;@name&lt;/code&gt; is not empty. Well, this is probably the bug: it shouldn’t allow &lt;code&gt;nil&lt;/code&gt; values too.&lt;/p&gt;

&lt;p&gt;Before we run to fix this bug, let’s confirm our thesis &lt;strong&gt;by writing a test that reproduces the error&lt;/strong&gt;. This is very important! If our test fails with the &lt;em&gt;same error&lt;/em&gt; that the monitoring tool had, we’re on the right track.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserTest&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Test&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Unit&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;TestCase&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_that_user_with_name_is_valid&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Matz'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;refute&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invalid?&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_that_user_with_empty_name_is_invalid&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invalid?&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_that_user_with_nil_name_is_invalid&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;-- New test here&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invalid?&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_that_can_save_user_with_name&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Matz'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;assert_equal&lt;/span&gt; &lt;span class="ss"&gt;:saved_on_db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save!&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_that_cannot_save_user_with_empty_name&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;assert_raise_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Cannot save invalid user!'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save!&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We run it and… BOOM!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: test_that_user_with_nil_name_is_invalid(UserTest):
  NoMethodError: undefined method `empty?' for nil:NilClass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, we’re able to reproduce the error. Now we must fix the bug, and if we patch it correctly, this test will pass.&lt;/p&gt;

&lt;p&gt;We should check if user’s name isn’t &lt;code&gt;nil&lt;/code&gt; before checking it isn’t empty:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;BaseModel&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;invalid?&lt;/span&gt;
    &lt;span class="vi"&gt;@name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="vi"&gt;@name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;-- In Rails this could be written as `@name.blank?`&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We rerun our tests, and now we’re green!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Loaded suite /your_app/tests/user_test
Started
.....
Finished in 0.000720944 seconds.
-------------------------------------------------------------------------------
5 tests, 5 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  We TDDed, so…?
&lt;/h2&gt;

&lt;p&gt;With this approach, we’ve not only fixed the bug but &lt;strong&gt;added a test confirming our fix&lt;/strong&gt; (making sure the error doesn’t happen again). Now, just open a Merge Request for it (or push to master you’re feeling rebel enough).&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DL
&lt;/h2&gt;

&lt;p&gt;Let’s review the steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identify the bug;&lt;/li&gt;
&lt;li&gt;Write a test that reproduces the error; &lt;em&gt;(This is the critical step)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Fix the bug;&lt;/li&gt;
&lt;li&gt;Watch the test pass.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I hope this helps you too see some TDD niceties! Happy TDDing!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>tdd</category>
      <category>ruby</category>
    </item>
  </channel>
</rss>
