<?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: DeepSource</title>
    <description>The latest articles on DEV Community by DeepSource (@deepsource).</description>
    <link>https://dev.to/deepsource</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%2Forganization%2Fprofile_image%2F875%2F507a2abb-98ae-499b-ab58-f37b70a058f7.png</url>
      <title>DEV Community: DeepSource</title>
      <link>https://dev.to/deepsource</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/deepsource"/>
    <language>en</language>
    <item>
      <title>JavaScript best practices to improve code quality</title>
      <dc:creator>Saif Sadiq</dc:creator>
      <pubDate>Mon, 19 Apr 2021 09:58:30 +0000</pubDate>
      <link>https://dev.to/deepsource/javascript-best-practices-to-improve-code-quality-5d33</link>
      <guid>https://dev.to/deepsource/javascript-best-practices-to-improve-code-quality-5d33</guid>
      <description>&lt;p&gt;If you write JavaScript today, it’s worth your time staying in the know of all the updates the language has seen in the past few years. Since 2015, with the release of ES6, a new version of the ECMAScript spec has been released each year. Each iteration adds new features, new syntax, and Quality of Life improvements to the language. JavaScript engines in most browsers and Node.js quickly catch up, and it’s only fair that your code should catch up as well. That’s because with each new iteration of JavaScript comes new idioms and new ways to express your code, and many a time, these changes may make the code more maintainable for you and your collaborators.&lt;/p&gt;

&lt;p&gt;Here are some of the latest ECMAScript features, and by induction, JavaScript and Node.js that you can make use of to write cleaner, more concise, and more readable code.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Block scored declarations
&lt;/h2&gt;

&lt;p&gt;Since the inception of the language, JavaScript developers have used &lt;code&gt;var&lt;/code&gt; to declare variables. The keyword &lt;code&gt;var&lt;/code&gt; has its quirks, the most problematic of those being the scope of the variables created by using 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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="c1"&gt;// inner declaration overrides declaration in parent scope&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="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// prints 15&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="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// prints 15&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since variables defined with &lt;code&gt;var&lt;/code&gt; are not block-scoped, redefining them in a narrower scope affects the value of the outer scope.&lt;/p&gt;

&lt;p&gt;Now we have two new keywords that replace &lt;code&gt;var&lt;/code&gt;, namely &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; that do not suffer from this drawback.&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;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="c1"&gt;// inner declaration is scoped within the if block&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="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// prints 15&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="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// prints 10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;const&lt;/code&gt; and &lt;code&gt;let&lt;/code&gt; differ in the semantics that variables declared with &lt;code&gt;const&lt;/code&gt; cannot be reassigned in their scope. This does not mean they are immutable, only that their references cannot be changed.&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;const&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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="p"&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="nx"&gt;x&lt;/span&gt; &lt;span class="c1"&gt;// ["Hello", "World!"]&lt;/span&gt;

&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="c1"&gt;// TypeError: Attempted to assign to readonly property.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Arrow functions
&lt;/h2&gt;

&lt;p&gt;Arrow functions are another very important feature introduced recently to JavaScript. They come bearing many advantages. First and foremost, they make the functional aspects of JavaScript beautiful to look at and simpler to write.&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;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;val&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="c1"&gt;// [2, 4, 6, 8]&lt;/span&gt;
&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// [2, 4]&lt;/span&gt;
&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In all of the above examples the arrow functions, named after the distinctive arrow &lt;code&gt;=&amp;gt;&lt;/code&gt;, replace traditional functions with a concise syntax.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If the function body is a single expression, the scope brackets &lt;code&gt;{}&lt;/code&gt; and &lt;code&gt;return&lt;/code&gt; keyword are implied and need not be written.&lt;/li&gt;
&lt;li&gt;If the function has a single argument, the argument parentheses &lt;code&gt;()&lt;/code&gt; are implied and need not be written.&lt;/li&gt;
&lt;li&gt;If the function body expression is a dictionary, it must be enclosed in parentheses &lt;code&gt;()&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Another significant advantage of arrow functions is that they do not define a scope but rather exist within the parent scope. This avoids a lot of pitfalls that can arise with the use of the &lt;code&gt;this&lt;/code&gt; keyword. Arrow functions have no bindings for &lt;code&gt;this&lt;/code&gt;. Inside the arrow function, the value of &lt;code&gt;this&lt;/code&gt; is the same as that in the parent scope. Consequently, arrow functions cannot be used as methods or constructors. Arrow functions don’t work with &lt;code&gt;apply&lt;/code&gt;, &lt;code&gt;bind&lt;/code&gt;, or &lt;code&gt;call&lt;/code&gt; and have no bindings for &lt;code&gt;super&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;They also have certain other limitations such as lack of the &lt;code&gt;arguments&lt;/code&gt; object which traditional functions can access and the inability to &lt;code&gt;yield&lt;/code&gt; from the function body.&lt;/p&gt;

&lt;p&gt;Thus arrow functions are not a 1:1 replacement for standard functions but welcome addition to JavaScript’s feature set.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Optional chaining
&lt;/h2&gt;

&lt;p&gt;Imagine a deeply nested data structure like this &lt;code&gt;person&lt;/code&gt; object here. Consider you wanted to access the first and last name of this person. You would write this in JavaScript like so:&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;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;last&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Doe&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="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt; &lt;span class="c1"&gt;// 'John'&lt;/span&gt;
&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;last&lt;/span&gt; &lt;span class="c1"&gt;// 'Doe'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now imagine what would happen if the &lt;code&gt;person&lt;/code&gt; object did not contain a nested &lt;code&gt;name&lt;/code&gt; object.&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;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt; &lt;span class="c1"&gt;// TypeError: Cannot read property 'first' of undefined&lt;/span&gt;
&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;last&lt;/span&gt; &lt;span class="c1"&gt;// TypeError: Cannot read property 'last' of undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To avoid such errors, developers had to resort to code like the following, which is unnecessarily verbose, hard to read, and unpleasant to write — a very bad trio of adjectives.&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;person&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meet optional chaining, a new feature of JavaScript that does away with this monstrosity. Optional chaining short-circuits the digging process as soon as it encounters a &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt; value and returns &lt;code&gt;undefined&lt;/code&gt; without raising an error.&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;person&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resultant code is much concise and cleaner.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Null-ish coalescing
&lt;/h2&gt;

&lt;p&gt;Before introducing the null-ish coalescing operator, JavaScript developers used the OR operator &lt;code&gt;||&lt;/code&gt; to fall back to a default value if the input was absent. This came with a significant caveat that even legitimate but falsy values would result in a fallback to the defaults.&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;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Missing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 'Missing'&lt;/span&gt;
&lt;span class="nf"&gt;print&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;// 'Missing'&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 'Missing'&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 'Missing'&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 'Missing'&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 'Missing'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JavaScript has now proposed the null coalescing operator &lt;code&gt;??&lt;/code&gt;, which offers a better alternative in that it only results in a fallback if the preceding expression is null-ish. Here null-ish refers to values that are &lt;code&gt;null&lt;/code&gt; or &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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Missing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 'Missing'&lt;/span&gt;
&lt;span class="nf"&gt;print&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;// 'Missing'&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ''&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// NaN&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, you can ensure that if your program accepts falsy values as legitimate inputs, you won’t end up replacing them with fallbacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Logical assignment
&lt;/h2&gt;

&lt;p&gt;Let’s say you want to assign a value to a variable if and only if the value is currently null-ish. A logical way to write this would be like so:&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you knew about how short-circuiting works, you might want to replace those 3 lines of code with a more succinct version using the null-ish coalescing operator.&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;x&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// x = y if x is nullish, else no effect&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we use the short-circuiting feature of the null-ish coalescing operator to execute the second part &lt;code&gt;x = y&lt;/code&gt; if &lt;code&gt;x&lt;/code&gt; is null-ish. The code is pretty concise, but it still is not very easy to read or understand. The logical null-ish assignment does away with the need for such a workaround.&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;x&lt;/span&gt; &lt;span class="o"&gt;??=&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="c1"&gt;// x = y if x is nullish, else no effect&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Along the same lines, JavaScript also introduces logical AND assignment &lt;code&gt;&amp;amp;&amp;amp;=&lt;/code&gt; and logical OR assignment &lt;code&gt;||=&lt;/code&gt; operators. These operators perform assignment only when the specific condition is met and have no effect otherwise.&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;x&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="c1"&gt;// x = y if x is falsy, else no effect&lt;/span&gt;
&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;=&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="c1"&gt;// x = y if x is truthy, else no effect&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pro-tip:&lt;/strong&gt; If you’ve written Ruby before, you’ve seen the &lt;code&gt;||=&lt;/code&gt; and &lt;code&gt;&amp;amp;&amp;amp;=&lt;/code&gt; operators, since Ruby does not have the concept of falsy values.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Named capture groups
&lt;/h2&gt;

&lt;p&gt;Let’s start with a quick recap of capture groups in regular expressions. A capture group is a part of the string that matches a portion of regex in parentheses.&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;let&lt;/span&gt; &lt;span class="nx"&gt;re&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(\d{4})&lt;/span&gt;&lt;span class="sr"&gt;-&lt;/span&gt;&lt;span class="se"&gt;(\d{2})&lt;/span&gt;&lt;span class="sr"&gt;-&lt;/span&gt;&lt;span class="se"&gt;(\d{2})&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pi day this year falls on 2021-03-14!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// '2020-03-14', the complete match&lt;/span&gt;
&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// '2020', the first capture group&lt;/span&gt;
&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// '03', the second capture group&lt;/span&gt;
&lt;span class="nx"&gt;result&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="c1"&gt;// '14', the third capture group&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Regular expressions have also supported named capture groups for quite some time, which is a way for the capture groups to be referenced by a name rather than an index. Now, with ES9, this feature has made its way to JavaScript. Now the result object contains a nested groups object where each capture group’s value is mapped to its name.&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;let&lt;/span&gt; &lt;span class="nx"&gt;re&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(?&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;year&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\d{4})&lt;/span&gt;&lt;span class="sr"&gt;-&lt;/span&gt;&lt;span class="se"&gt;(?&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;month&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\d{2})&lt;/span&gt;&lt;span class="sr"&gt;-&lt;/span&gt;&lt;span class="se"&gt;(?&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;day&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\d{2})&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pi day this year falls on 2021-03-14!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt; &lt;span class="c1"&gt;// '2020', the group named 'year'&lt;/span&gt;
&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;month&lt;/span&gt; &lt;span class="c1"&gt;// '03', the group named 'month'&lt;/span&gt;
&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;day&lt;/span&gt; &lt;span class="c1"&gt;// '14', the group named 'day'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The new API works beautifully with another new JavaScript feature, de-structured assignments.&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;let&lt;/span&gt; &lt;span class="nx"&gt;re&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(?&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;year&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\d{4})&lt;/span&gt;&lt;span class="sr"&gt;-&lt;/span&gt;&lt;span class="se"&gt;(?&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;month&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\d{2})&lt;/span&gt;&lt;span class="sr"&gt;-&lt;/span&gt;&lt;span class="se"&gt;(?&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;day&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\d{2})&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pi day this year falls on 2021-03-14!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;day&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;groups&lt;/span&gt; &lt;span class="nx"&gt;year&lt;/span&gt; &lt;span class="c1"&gt;// '2020'&lt;/span&gt;
&lt;span class="nx"&gt;month&lt;/span&gt; &lt;span class="c1"&gt;// '03'&lt;/span&gt;
&lt;span class="nx"&gt;day&lt;/span&gt; &lt;span class="c1"&gt;// '14'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. &lt;code&gt;async&lt;/code&gt; &amp;amp; &lt;code&gt;await&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;One of the powerful aspects of JavaScript is its asynchronicity. This means that many functions that may be long-running or time-consuming can return a Promise and not block execution.&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;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://the-one-api.dev/v2/book&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;prom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;prom&lt;/span&gt; &lt;span class="c1"&gt;// Promise {&amp;lt;pending&amp;gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// wait a bit&lt;/span&gt;
&lt;span class="nx"&gt;prom&lt;/span&gt; &lt;span class="c1"&gt;// Promise {&amp;lt;fullfilled&amp;gt;: Response}, if no errors&lt;/span&gt;
&lt;span class="c1"&gt;// or&lt;/span&gt;
&lt;span class="nx"&gt;prom&lt;/span&gt; &lt;span class="c1"&gt;// Promise {&amp;lt;rejected&amp;gt;: Error message}, if any error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the call to fetch returns a Promise that has the status ‘pending’ when created. Soon, when the API returns the response, it transitions into a ‘fulfilled’ state, and the Response that it wraps can be accessed. In the Promises world, you would do something like this to make an API call and parse the response as JSON.&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;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://the-one-api.dev/v2/book&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;prom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;prom&lt;/span&gt; &lt;span class="c1"&gt;// Promise {&amp;lt;fullfilled&amp;gt;: Response}&lt;/span&gt;
 &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// prints response, if no errors&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;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// prints error message, if any error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In 2017, JavaScript announced two new keywords &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt;, that make handling and working with Promises easier and more fluent. They are not a replacement for Promises; they are merely syntactic sugar on top of the powerful Promises concepts.&lt;/p&gt;

&lt;p&gt;Instead of all the code happening inside a series of ‘then’ functions, &lt;code&gt;await&lt;/code&gt; makes it all look like synchronous JavaScript. As an added benefit, you can use &lt;code&gt;try...catch&lt;/code&gt; with &lt;code&gt;await&lt;/code&gt; instead of handling errors in ‘catch’ functions as you would have to if consuming Promises directly. The same code with &lt;code&gt;await&lt;/code&gt; would look 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://the-one-api.dev/v2/book&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Promise {&amp;lt;fullfilled&amp;gt;: Response} -await-&amp;gt; Response&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// prints response, if no errors&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;err&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="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// prints error message, if any error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;async&lt;/code&gt; keyword is the other side of the same coin, in that it wraps any data to be sent within a Promise. Consider the following asynchronous function for adding several numbers. In the real world, your code would be doing something much more complicated.&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;agg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;agg&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&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="c1"&gt;// Promise {&amp;lt;fulfilled&amp;gt;: 6}&lt;/span&gt;
 &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// prints 6&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&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="c1"&gt;// Promise {&amp;lt;fulfilled&amp;gt;: 6} -await-&amp;gt; 6&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// prints 6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These new features just the tip of the iceberg. We have barely even scratched the surface. JavaScript is constantly evolving, and new features are added to the language every year. It’s tough to keep up with the constant barrage of new features and idioms introduced to the language manually.&lt;/p&gt;

&lt;p&gt;Wouldn’t it be nice if some tool could handle this for us? Fret not, there is. We’ve already talked in detail about &lt;a href="https://deepsource.io/blog/static-analysis-javascript/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=contentdistribution&amp;amp;utm_term=jscodequality" rel="noopener noreferrer"&gt;setting up static code analysis in your JavaScript repo&lt;/a&gt; using ESLint. It’s extremely useful and should be an indispensable tool of your toolchain. But to be honest, setting up ESLint auto-fix pipelines and processes takes time and effort. Unless you enjoy this sort of plumbing, you’d be better off if you wrote the code and outsourced the plumbing to…DeepSource!&lt;/p&gt;

&lt;p&gt;DeepSource can help you with &lt;a href="https://deepsource.io/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=contentdistribution&amp;amp;utm_term=jscodequality" rel="noopener noreferrer"&gt;automating the code reviews&lt;/a&gt; and save you a ton of time. Just add a &lt;code&gt;.deepsource.toml&lt;/code&gt; file in the root of the repository and DeepSource will pick it up for scanning right away. The scan will find scope for improvements across your code and help you fix them with helpful descriptions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://deepsource.io/signup?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=contentdistribution&amp;amp;utm_term=jscodequality" rel="noopener noreferrer"&gt;Sign up&lt;/a&gt; and see for yourself!&lt;/p&gt;

&lt;p&gt;Originally published on &lt;a href="https://deepsource.io/blog/javascript-code-quality-best-practices/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=contentdistribution&amp;amp;utm_term=jscodequality" rel="noopener noreferrer"&gt;DeepSource Blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>codequality</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Guidelines for Java code reviews</title>
      <dc:creator>Saif Sadiq</dc:creator>
      <pubDate>Mon, 12 Apr 2021 05:57:10 +0000</pubDate>
      <link>https://dev.to/deepsource/guidelines-for-java-code-reviews-3096</link>
      <guid>https://dev.to/deepsource/guidelines-for-java-code-reviews-3096</guid>
      <description>&lt;p&gt;Having another pair of eyes scan your code is always useful and helps you spot mistakes before you break production. You need not be an expert to review someone’s code. Some experience with the programming language and a review checklist should help you get started. We’ve put together a list of things you should keep in mind when you’re reviewing Java code. Read on!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Follow Java code conventions
&lt;/h2&gt;

&lt;p&gt;Following language conventions helps quickly skim through the code and make sense of it, thereby improving readability. For instance, all package names in Java are written in lowercase, constants in all caps, variable names in CamelCase, etc. Find the complete list of conventions &lt;a href="https://www.oracle.com/technetwork/java/codeconventions-150003.pdf" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Some teams develop their own conventions, so be flexible in such cases!&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Replace imperative code with lambdas and streams
&lt;/h2&gt;

&lt;p&gt;If you’re using Java 8+, replacing loops and extremely verbose methods with streams and lambdas makes the code look cleaner. Lambdas and streams allow you to write functional code in Java. The following snippet filters odd numbers in the traditional imperative way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;oddNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&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;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;oddNumbers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the functional way of filtering odd numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;oddNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&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;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Beware of the &lt;code&gt;NullPointerException&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;When writing new methods, try to avoid returning nulls if possible. It could lead to null pointer exceptions. In the snippet below, the highest method returns a null if the list has no integers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Items&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="nf"&gt;highest&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;highest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;indexOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;highest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;highest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;highest&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;highest&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;highest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before directly calling a method on an object I recommend checking for nulls as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;emptyList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;highest&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;isEven&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// throws NullPointerException ❌&lt;/span&gt;
&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;isEven&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;// ✅&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can be pretty cumbersome to have null checks everywhere in your code though. If you are using Java 8+, consider using the &lt;code&gt;Optional&lt;/code&gt; class to represent values that may not have valid states. It allows you to easily define alternate behavior and is useful for chaining methods.&lt;/p&gt;

&lt;p&gt;In the snippet below, we are using Java Stream API to find the highest number with a method which returns an &lt;code&gt;Optional&lt;/code&gt;. Note that we are using &lt;code&gt;Stream.reduce&lt;/code&gt;, which returns an &lt;code&gt;Optional&lt;/code&gt; value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;highest&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reduce&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;integer2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
                            &lt;span class="n"&gt;integer&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;integer2&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;integer&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;integer2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;emptyList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;highest&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;ifPresent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;             &lt;span class="c1"&gt;// ✅&lt;/span&gt;
    &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;isEven&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;integer&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, you could also use annotations such as &lt;code&gt;@Nullable&lt;/code&gt; or &lt;code&gt;@NonNull&lt;/code&gt; which will result in warnings if there is a null conflict while building the code. For instance, passing a &lt;code&gt;@Nullable&lt;/code&gt; argument to a method that accepts &lt;code&gt;@NonNull&lt;/code&gt; parameters.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Directly assigning references from client code to a field
&lt;/h2&gt;

&lt;p&gt;References exposed to the client code can be manipulated even if the field is final. Let’s understand this better with an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Items&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above snippet, we directly assign a reference from the client code to a field. The client can easily mutate the contents of the list and manipulate our code as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// This will change how items behaves as well&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, consider cloning the reference or creating a new reference and then assigning it to the field as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Items&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same rule applies while returning references. You need to be cautious so as not to expose internal mutable state.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Handle exceptions with care
&lt;/h2&gt;

&lt;p&gt;While catching exceptions, if you have multiple catch blocks, ensure that the sequence of catch blocks is most specific to least. In the snippet below, the exception will never be caught in the second block since the &lt;code&gt;Exception&lt;/code&gt; class is the mother of all exceptions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pop&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// handle exception&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StackEmptyException&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// handle exception&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the situation is recoverable and can be handled by the client (the consumer of your library or code) then it is good to use checked exceptions. e. g. &lt;code&gt;IOException&lt;/code&gt; is a checked exception that forces the client to handle the scenario and in case the client chooses to re-throw the exception then it should be a conscious call to disregard the exception.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Ponder over the choice of data structures
&lt;/h2&gt;

&lt;p&gt;Java collections provide &lt;code&gt;ArrayList&lt;/code&gt;, &lt;code&gt;LinkedList&lt;/code&gt;, &lt;code&gt;Vector&lt;/code&gt;, &lt;code&gt;Stack&lt;/code&gt;, &lt;code&gt;HashSet&lt;/code&gt;, &lt;code&gt;HashMap&lt;/code&gt;, &lt;code&gt;Hashtable&lt;/code&gt;. It’s important to understand the pros and cons of each to use them in the correct context. A few hints to help you make the right choice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Map&lt;/code&gt;: Useful if you have unordered items in the form of key, value pairs and require efficient retrieval, insertion, and deletion operations. &lt;code&gt;HashMap&lt;/code&gt;, &lt;code&gt;Hashtable&lt;/code&gt;, &lt;code&gt;LinkedHashMap&lt;/code&gt; are all implementations of the &lt;code&gt;Map&lt;/code&gt; interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;List&lt;/code&gt;: Very commonly used to create an ordered list of items. This list may contain duplicates. &lt;code&gt;ArrayList&lt;/code&gt; is an implementation of the &lt;code&gt;List&lt;/code&gt; interface. A list can be made thread-safe using &lt;code&gt;Collections.synchronizedList&lt;/code&gt; thus removing the need for using &lt;code&gt;Vector&lt;/code&gt;. &lt;a href="https://javaconceptoftheday.com/not-use-vector-class-code/" rel="noopener noreferrer"&gt;Here&lt;/a&gt;’s some more info on why &lt;code&gt;Vector&lt;/code&gt; is essentially obsolete.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Set&lt;/code&gt;: Similar to list but does not allow duplicates. &lt;code&gt;HashSet&lt;/code&gt; implements the &lt;code&gt;Set&lt;/code&gt; interface.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Think twice before you expose
&lt;/h2&gt;

&lt;p&gt;There are quite a few access modifiers to choose from in Java — &lt;code&gt;public&lt;/code&gt;, &lt;code&gt;protected&lt;/code&gt;, &lt;code&gt;private&lt;/code&gt;. Unless you want to expose a method to the client code, you might want to keep everything &lt;code&gt;private&lt;/code&gt; by default. Once you expose an API, there’s no going back.&lt;/p&gt;

&lt;p&gt;For instance, you have a class &lt;code&gt;Library&lt;/code&gt; that has the following method to checkout a book by name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;checkout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;bookName&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;searchByTitle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;availableBooks&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bookName&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;availableBooks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;checkedOutBooks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;searchByTitle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;availableBooks&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;bookName&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you do not keep the &lt;code&gt;searchByTitle&lt;/code&gt; method private by default and it ends up being exposed, other classes could start using it and building logic on top of it that you may have wanted to be part of the &lt;code&gt;Library&lt;/code&gt; class. It could break the encapsulation of the &lt;code&gt;Library&lt;/code&gt; class or it may be impossible to revert/modify later without breaking someone else’s code. Expose consciously!&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Code to interfaces
&lt;/h2&gt;

&lt;p&gt;If you have concrete implementations of certain interfaces (e. g. &lt;code&gt;ArrayList&lt;/code&gt; or &lt;code&gt;LinkedList&lt;/code&gt;) and if you use them directly in your code, then it can lead to high coupling. Sticking with the &lt;code&gt;List&lt;/code&gt; interface enables you to switch over the implementation any time in the future without breaking any code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Bill&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Printer&lt;/span&gt; &lt;span class="n"&gt;printer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;printer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Bill&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ConsolePrinter&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Bill&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HTMLPrinter&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above snippet, using the &lt;code&gt;Printer&lt;/code&gt; interface allows the developer to move to another concrete class &lt;code&gt;HTMLPrinter&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Don’t force fit interfaces
&lt;/h2&gt;

&lt;p&gt;Take a look at the following interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;BookService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fetchBooks&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;saveBooks&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;order&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;OrderDetails&lt;/span&gt; &lt;span class="n"&gt;orderDetails&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;BookNotFoundException&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BookUnavailableException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;   
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookServiceImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;BookService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is there a benefit of creating such an interface? Is there a scope for this interface being implemented by another class? Is this interface generic enough to be implemented by another class? If the answer to all these questions is no, then I’d definitely recommend avoiding this unnecessary interface that you’ll have to maintain in the future. Martin Fowler explains this really well in his &lt;a href="https://martinfowler.com/bliki/InterfaceImplementationPair.html" rel="noopener noreferrer"&gt;blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Well then, what’s a good use case for an interface? Let’s say we have a &lt;code&gt;class Rectangle&lt;/code&gt; and a &lt;code&gt;class Circle&lt;/code&gt; that has behavior to calculate perimeter. If there is a requirement, to sum up, the perimeter of all shapes — a use case for polymorphism, then having the interface would make more sense, as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Double&lt;/span&gt; &lt;span class="nf"&gt;perimeter&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Rectangle&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;//data members and constructors&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Double&lt;/span&gt; &lt;span class="nf"&gt;perimeter&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;breadth&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Circle&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;//data members and constructors&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Double&lt;/span&gt; &lt;span class="nf"&gt;perimeter&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PI&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;totalPerimeter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Shape&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;shapes&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;shapes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
               &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Shape:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;perimeter&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
               &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reduce&lt;/span&gt;&lt;span class="o"&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="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Double&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sum&lt;/span&gt;&lt;span class="o"&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="o"&gt;))&lt;/span&gt;
               &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseGet&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  10. Override hashCode when overriding equals
&lt;/h2&gt;

&lt;p&gt;Objects that are equal because of their values are called &lt;a href="https://martinfowler.com/bliki/ValueObject.html" rel="noopener noreferrer"&gt;value objects&lt;/a&gt;. e. g. money, time. Such classes must override the &lt;code&gt;equals&lt;/code&gt; method to return true if the values are the same. The &lt;code&gt;equals&lt;/code&gt; method is usually used by other libraries for comparison and equality checks; hence overriding &lt;code&gt;equals&lt;/code&gt; is necessary. Each Java object also has a hash code value that differentiates it from another object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Coin&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;Coin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;Coin&lt;/span&gt; &lt;span class="n"&gt;coin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Coin&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;coin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, we have overridden only the &lt;code&gt;equals&lt;/code&gt; method of &lt;code&gt;Object&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Coin&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;coinCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Coin&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;()&lt;/span&gt; &lt;span class="o"&gt;{{&lt;/span&gt;
  &lt;span class="n"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Coin&lt;/span&gt;&lt;span class="o"&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;5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Coin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}};&lt;/span&gt;

&lt;span class="c1"&gt;//update count for 1 rupee coin&lt;/span&gt;
&lt;span class="n"&gt;coinCount&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Coin&lt;/span&gt;&lt;span class="o"&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;7&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;coinCount&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 3 🤯 why? &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We would expect &lt;code&gt;coinCount&lt;/code&gt; to update the number of 1 rupee coins to 7 since we override equals. But &lt;code&gt;HashMap&lt;/code&gt; internally checks if the hash code for 2 objects is equal and only then proceeds to test equality via the &lt;code&gt;equals&lt;/code&gt; method. Two different objects may or may not have the same hash code but two equal objects must always have the same hash code, as defined by the contract of the &lt;code&gt;hashCode&lt;/code&gt; method. So checking for hash code first is an early exit condition. This implies that both &lt;code&gt;equals&lt;/code&gt; and &lt;code&gt;hashCode&lt;/code&gt; methods must be overridden to express equality.&lt;/p&gt;

&lt;p&gt;If you write or review Java code, DeepSource can help you with &lt;a href="https://deepsource.io/blog/code-review-best-practices/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=contentdistribution&amp;amp;utm_term=javacodereview" rel="noopener noreferrer"&gt;automating the code reviews&lt;/a&gt; and save you a ton of time. Just add a &lt;code&gt;.deepsource.toml&lt;/code&gt; file in the root of the repository and DeepSource will pick it up for scanning right away. The scan will find scope for improvements across your code and help you fix them with helpful descriptions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://deepsource.io/signup/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=contentdistribution&amp;amp;utm_term=javacodereview" rel="noopener noreferrer"&gt;Sign up&lt;/a&gt; and see for yourself!&lt;/p&gt;

</description>
      <category>java</category>
      <category>codereview</category>
      <category>programming</category>
    </item>
    <item>
      <title>Python code review checklist</title>
      <dc:creator>Saif Sadiq</dc:creator>
      <pubDate>Tue, 30 Mar 2021 13:22:22 +0000</pubDate>
      <link>https://dev.to/deepsource/python-code-review-checklist-h30</link>
      <guid>https://dev.to/deepsource/python-code-review-checklist-h30</guid>
      <description>&lt;p&gt;As developers, we are all too familiar with code reviews. Having another pair of eyes take a look at our code can be wonderful; it shows us so many aspects of our code we would not have noticed otherwise. A code review can be informative, and it can be educational. I can confidently attribute most of what I know about good programming practices to code reviews.&lt;/p&gt;

&lt;p&gt;The amount of learning a reviewee takes away from a code review depends on how well the review is performed. It thus falls on the reviewer to make their review count by packing the most lessons into the review as possible.&lt;/p&gt;

&lt;p&gt;This is a guide on some vital aspects of the code you should be checking in your reviews, the expectations you should have from those checks, and some ideas on how tooling (such as linters, formatters, and test suites) can help streamline the process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code review checklist
&lt;/h2&gt;

&lt;p&gt;We have formulated this guide in the form of a checklist. It lists a set of questions that you need to ask about the code. If the answer to any of them is not a ‘yes’, you should leave a remark on the PR.&lt;/p&gt;

&lt;p&gt;Do note that this list is only meant to serve as a guideline. Your codebase, like every codebase, has its own specific set of needs, so feel free to build upon this guide and override pieces of it that do not fit well for your use-cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Etiquettes
&lt;/h3&gt;

&lt;p&gt;The first and foremost thing to check during a review is how closely the PR adheres to basic etiquettes. Good PRs are composed of bite-sized changes and solve a single well-defined problem. They should be focused and purposefully narrow to have as few merge conflicts as possible. Put simply, a good PR facilitates being reviewed.&lt;/p&gt;

&lt;p&gt;For large-scale swooping changes, make a separate target branch and then make small incremental PRs to that target, finally merging the target with the main branch. Making one humongous PR makes it harder to review, and if it goes stale, many merge conflicts may pop up.&lt;/p&gt;

&lt;p&gt;When reviewing PRs from new developers, I also make it a point to ensure their commit messages are &lt;a href="https://www.git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project#_commit_guidelines" rel="noopener noreferrer"&gt;well-written&lt;/a&gt;.&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%2Fcig7dwlv1bp2jg6qkop2.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%2Fcig7dwlv1bp2jg6qkop2.png" alt="Alt Text" width="439" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checklist:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the PR atomic?&lt;/li&gt;
&lt;li&gt;Does the PR follow the single concern principle?&lt;/li&gt;
&lt;li&gt;Are the commit messages well-written?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideas:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enforce a commit message format in the team. For example, you could try &lt;a href="https://gitmoji.dev" rel="noopener noreferrer"&gt;gitmoji&lt;/a&gt; wherein you use emoji in commit messages. For example, bugfixes should start with &lt;code&gt;[FIX]&lt;/code&gt;, or the 🐛 emoji and new features should start with &lt;code&gt;[FEAT]&lt;/code&gt; or the ✨ emoji. This makes the intention of the commit very clear.&lt;/p&gt;

&lt;h3&gt;
  
  
  Functionality and syntax
&lt;/h3&gt;

&lt;p&gt;The next thing to check is whether the PR is effective in that it works. Code changed by the PR should work as expected. A bug fix should solve the bug it was supposed to fix. A feature should provide the additional functionality that was required without breaking something else.&lt;/p&gt;

&lt;p&gt;An important thing to keep in mind is that any new feature added by a PR is justified. A simple way to ensure this is to accept only the PRs that are associated with an already triaged issue. This practice minimizes &lt;a href="https://en.wikipedia.org/wiki/Feature_creep" rel="noopener noreferrer"&gt;feature-creep&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checklist:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the PR work?&lt;/li&gt;
&lt;li&gt;Does the new feature add value or is it a sign of feature-creep?&lt;/li&gt;
&lt;li&gt;Does the PR add test-cases for the modified code?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideas:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Having comprehensive tests in the code makes it easier to check that new functionality works and harder for PRs to break existing stuff. The portion of the code covered should never go down in a PR. Any new code should come with complete coverage in unit/functional tests. Python comes with a robust &lt;a href="https://docs.python.org/3.9/library/unittest.html" rel="noopener noreferrer"&gt;unit testing framework&lt;/a&gt; built into the language itself. You should make use of it in your codebase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design
&lt;/h3&gt;

&lt;p&gt;Once we’ve established that the code works, the next step is to check how well it integrates with the existing codebase. One key thing to inspect in this regard is duplication. Often, code added to a repo provides functionality that might already be a part of the code in a different location or something provided by the frameworks or Pip packages in use. This knowledge is something that one can only gain by experience. As a senior, it becomes your duty to point such duplication out to new developers contributing to your repo.&lt;/p&gt;

&lt;p&gt;Attention to paradigms is also essential. Many projects have pre-adopted design paradigms such as microservices, mono repo, or cloud-nativity. Any incoming code should be in line with these paradigms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checklist:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the code properly planned and designed?&lt;/li&gt;
&lt;li&gt;Will the code work well with the existing code and not increase duplication?&lt;/li&gt;
&lt;li&gt;Is the code well organised in terms of placement of components?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Patterns and idioms
&lt;/h3&gt;

&lt;p&gt;Python is a very mature language. It is driven based on certain philosophies, described as &lt;a href="https://www.python.org/dev/peps/pep-0020/" rel="noopener noreferrer"&gt;the Zen of Python&lt;/a&gt;. Those philosophies have given birth to many conventions and idioms that new code is expected to follow.&lt;/p&gt;

&lt;p&gt;The difference between idiomatic and non-idiomatic code is very subtle, and in most cases, can only be intuitively gauged. As with all things honed by experience, intuition must be transferred from experienced people, like yourself, to newbies like your reviewees.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checklist:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the code keep with the idioms and code patterns of the language?&lt;/li&gt;
&lt;li&gt;Does the code make use of the language features and standard libraries?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideas:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most linters, popularly &lt;a href="https://www.pylint.org" rel="noopener noreferrer"&gt;PyLint&lt;/a&gt;, can help you identify deviations from the style guides and, in most cases, even automatically fix them. Linters work incredibly fast and can make corrections to the code in real-time, making them a valuable addition to your toolchain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Readability
&lt;/h3&gt;

&lt;p&gt;Python is widely regarded as a very readable language. Python’s simplicity of syntax and reduced usage of punctuation contribute heavily to its readability. It only makes sense for code written in the language to be readable as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checklist:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the code clear and concise?&lt;/li&gt;
&lt;li&gt;Does it comply with PEP-8?&lt;/li&gt;
&lt;li&gt;Are all language and project conventions followed?&lt;/li&gt;
&lt;li&gt;Are identifiers given meaningful and style guide-compliant names?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideas:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A good code formatter like &lt;a href="https://black.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;Black&lt;/a&gt; can help a lot in formatting the code for consistency and readability. Black also offers minimal customization, which is good because it eliminates all forms of &lt;a href="https://en.wikipedia.org/wiki/Law_of_triviality" rel="noopener noreferrer"&gt;bikeshedding&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We’ve previously talked about &lt;a href="https://deepsource.io/blog/auto-code-formatting-python/?utm_source=devto&amp;amp;utm_term=pythoncodereview&amp;amp;utm_campaign=contentdistribution" rel="noopener noreferrer"&gt;integrating Black into your CI pipeline&lt;/a&gt; can work wonders during a code review.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentation and maintainability
&lt;/h3&gt;

&lt;p&gt;The next thing to check is the maintainability of the code. Any code added or changed by the PR should be written to facilitate someone other than the original author to maintain it.&lt;/p&gt;

&lt;p&gt;It should preferably be self-documenting, which means written in a way that anyone reading the code may be able to understand what it does. This is one of the hallmarks of good Python code. If the code has to be complex by design, it should be amply documented. In an ideal world, all classes and functions would have Python docstrings, complete with examples.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checklist:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the code self-documenting or well-documented?&lt;/li&gt;
&lt;li&gt;Is the code free of obfuscation and unnecessary complexity?&lt;/li&gt;
&lt;li&gt;Is the control flow and component relationship clear to understand?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideas:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.sphinx-doc.org/en/master/" rel="noopener noreferrer"&gt;Sphinx&lt;/a&gt; is a documentation generator that exports beautiful documentation from Python docstrings. The exported documentation can then be uploaded to &lt;a href="https://rtfd.io" rel="noopener noreferrer"&gt;ReadTheDocs&lt;/a&gt;, a popular doc-hosting tool. Sphinx is one of the main reasons why I absolutely love writing documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;p&gt;Ensuring that the application remains secure is critical. The next thing to check is if the PR maintains or improves the security of the project. You need to ensure that the changes do not increase the attack surface area or expose vulnerabilities. If the PR adds new dependencies, they could potentially be unsafe, in which case you might need to check the version for known exploits and update the dependencies, if necessary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checklist:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the code free of implementation bugs that could be exploited?&lt;/li&gt;
&lt;li&gt;Have all the new dependencies been audited for vulnerabilities?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideas:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the renowned security analyzers for Python is &lt;a href="https://github.com/PyCQA/bandit" rel="noopener noreferrer"&gt;Bandit&lt;/a&gt;. Also, if you use GitHub for hosting code, you should absolutely read &lt;a href="https://docs.github.com/en/github/managing-security-vulnerabilities" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; about setting up vulnerability detection and Dependabot for your codebase.&lt;/p&gt;

&lt;p&gt;Once you set up vulnerability detection on GitHub, you’ll get notifications like this…&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%2Flx03nhs71gbxp8zyttk1.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%2Flx03nhs71gbxp8zyttk1.png" alt="Alt Text" width="800" height="28"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;… with details about the vulnerability and PRs in your repositories that you can merge to patch them.&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%2Fesrdoe7w1pg9c8i8fc3u.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%2Fesrdoe7w1pg9c8i8fc3u.png" alt="Alt Text" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We’ve also recently talked about &lt;a href="https://deepsource.io/blog/python-security-pitfalls/?utm_source=devto&amp;amp;utm_term=pythoncodereview&amp;amp;utm_campaign=contentdistribution" rel="noopener noreferrer"&gt;common security pitfalls in Python&lt;/a&gt; development and how you can secure your projects against them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance, reliability and scalability
&lt;/h3&gt;

&lt;p&gt;The final things to check are the performance and reliability of the code at scale. While these are undoubtedly key metrics, I put them on the bottom of the checklist because I believe well-planned, well-designed, and well-written code generally works well too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checklist:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the code optimised for in terms of time and space complexity?&lt;/li&gt;
&lt;li&gt;Does it scale as per the need?&lt;/li&gt;
&lt;li&gt;Does it have instrumentation like reporting for metrics and alerting for failures?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideas:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An excellent way to have add some reliability to Python is to use type hinting and static type checking that can provide hints into possible errors before runtime. Python new &lt;a href="https://www.python.org/dev/peps/pep-0484/" rel="noopener noreferrer"&gt;native support for type-hints&lt;/a&gt; is primarily inspired by the &lt;a href="http://www.mypy-lang.org" rel="noopener noreferrer"&gt;Mypy&lt;/a&gt; syntax, which can be incrementally adopted in existing projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  DeepSource
&lt;/h2&gt;

&lt;p&gt;DeepSource is an automated code review tool that manages the end-to-end code scanning process and automatically makes pull requests with fixes whenever new commits are pushed or new pull requests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://deepsource.io/docs/analyzer/python.html?utm_source=devto&amp;amp;utm_term=pythoncodereview&amp;amp;utm_campaign=contentdistribution" rel="noopener noreferrer"&gt;Setting up DeepSource for Python&lt;/a&gt; is a quick, easy, no-fuss process. Just add a &lt;code&gt;.deepsource.toml&lt;/code&gt; file in the root of the repo, and immediately DeepSource will pick it up for scanning. The scan will find scope for improvements across your codebase, make those improvements, and open pull requests for the changes it finds. I was blown away by the simplicity of the setup and the efficacy of their self-built code engine.&lt;/p&gt;

&lt;p&gt;🙋‍♂️ &lt;strong&gt;Trivia:&lt;/strong&gt; Did you know that DeepSource holds the distinction of being on &lt;a href="https://owasp.org/www-community/Source_Code_Analysis_Tools" rel="noopener noreferrer"&gt;OWASP’s curated list&lt;/a&gt; of source code analysis tools for Python?&lt;/p&gt;

&lt;h2&gt;
  
  
  The ideal code review
&lt;/h2&gt;

&lt;p&gt;Returning to my point about code reviews being educational and informative, I would also like to add that code reviews are time-consuming and resource-intensive. While each review takes time, the more in-depth and comprehensive ones consume even more.&lt;/p&gt;

&lt;p&gt;So each review must be as productive as possible. This is where all the tooling and automation efforts should be directed. By automating whatever can be automated, which is generally the mundane parts of the review, such as code style and formatting, we can allow devs to focus on the important stuff like architecture, design, and scalability.&lt;/p&gt;

&lt;p&gt;I’ll leave you with a profound thought my mentor shared with me.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A good code review not only improves the code but the coder as well.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>python</category>
      <category>codereview</category>
      <category>codereviewchecklist</category>
      <category>automatedcodereview</category>
    </item>
    <item>
      <title>Common anti-patterns in Go</title>
      <dc:creator>Saif Sadiq</dc:creator>
      <pubDate>Wed, 24 Mar 2021 06:05:42 +0000</pubDate>
      <link>https://dev.to/deepsource/common-anti-patterns-in-go-fm7</link>
      <guid>https://dev.to/deepsource/common-anti-patterns-in-go-fm7</guid>
      <description>&lt;p&gt;It has been widely acknowledged that coding is an art, and like every artisan who crafts wonderful art and is proud of them, we as developers are also really proud of the code we write. In order to achieve the best results, artists constantly keep searching for ways and tools to improve their craft. Similarly, we as developers keep levelling up our skills and remain curious to know the answer to the single most important question - &lt;strong&gt;“How to write good code”.&lt;/strong&gt; 🤯&lt;/p&gt;

&lt;p&gt;Frederick P. Brooks in his book “ &lt;strong&gt;The Mythical Man Month: Essays on Software Engineering&lt;/strong&gt; ” wrote :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by exertion of the imagination. Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structures.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&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%2Fucarecdn.com%2F76f98acb-ecc5-4701-9a61-409dc9062b4d%2F" 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%2Fucarecdn.com%2F76f98acb-ecc5-4701-9a61-409dc9062b4d%2F" alt="how-to-write-good-code.png" width="455" height="695"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image source: &lt;a href="https://xkcd.com/844/" rel="noopener noreferrer"&gt;https://xkcd.com/844/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This post tries to explore answers to the big question mark in the comic above. The simplest way to write good code is to abstain from including &lt;strong&gt;anti-patterns&lt;/strong&gt; in the code we write.😇&lt;/p&gt;

&lt;h2&gt;
  
  
  What are anti-patterns? 🤔
&lt;/h2&gt;

&lt;p&gt;Anti-patterns occur when code is written without taking future considerations into account. Anti-patterns might initially appear to be an appropriate solution to the problem, but, in reality, as the codebase scales, these come out to be obscure and add ‘technical debt’ to our codebase.&lt;/p&gt;

&lt;p&gt;A simple example of an anti-pattern is to write an API without considering how the consumers of the API might use it, as explained in example 1 below. Being aware of anti-patterns and consciously avoid using them while programming is surely a major step towards a more readable and maintainable codebase. In this post, let’s take a look at a few commonly seen anti-patterns in Go.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Returning value of unexported type from an exported function
&lt;/h3&gt;

&lt;p&gt;In Go, to &lt;code&gt;export&lt;/code&gt; any &lt;code&gt;field&lt;/code&gt; or &lt;code&gt;variable&lt;/code&gt; we need to make sure that its name starts with an uppercase letter. The motivation behind exporting them is to make them visible to other packages. For example, if we want to use the &lt;code&gt;Pi&lt;/code&gt; function from &lt;code&gt;math&lt;/code&gt; package, we should address it as &lt;code&gt;math.Pi&lt;/code&gt; . Using &lt;code&gt;math.pi&lt;/code&gt; won’t work and will error out.&lt;/p&gt;

&lt;p&gt;Names (struct fields, functions, variables) that start with a lowercase letter are unexported, and are only visible inside the package they are defined in.&lt;/p&gt;

&lt;p&gt;An exported function or method returning a value of an unexported type may be frustrating to use since callers of that function from other packages will have to define a type again to use it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Bad practice&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;unexportedType&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;ExportedFunc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;unexportedType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;unexportedType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"some string"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c"&gt;// Recommended&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;ExportedType&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;ExportedFunc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;ExportedType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ExportedType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"some string"&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;
  
  
  2. Unnecessary use of blank identifier
&lt;/h3&gt;

&lt;p&gt;In various cases, assigning value to a blank identifier is not needed and is unnecessary. In case of using the blank identifier in &lt;code&gt;for&lt;/code&gt; loop, the Go specification mentions :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If the last iteration variable is the blank identifier, the range clause is equivalent to the same clause without that identifier.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Bad practice&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;someMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="c"&gt;// Recommended&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;something&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;someMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Using loop/multiple &lt;code&gt;append&lt;/code&gt;s to concatenate two slices
&lt;/h3&gt;

&lt;p&gt;When appending multiple slices into one, there is no need to iterate over the slice and append each element one by one. Rather, it is much better and efficient to do that in a single &lt;code&gt;append&lt;/code&gt; statement.&lt;/p&gt;

&lt;p&gt;As an example, the below snippet does concatenation by appending elements one by one through iterating over &lt;code&gt;sliceTwo&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;sliceTwo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;sliceOne&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sliceOne&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&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;But, since we know that &lt;code&gt;append&lt;/code&gt; is a &lt;code&gt;variadic&lt;/code&gt; function and thus, it can be invoked with zero or more arguments. Therefore, the above example can be re-written in a much simpler way by using only one &lt;code&gt;append&lt;/code&gt; function call like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;sliceOne&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sliceOne&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sliceTwo&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Redundant arguments in &lt;code&gt;make&lt;/code&gt; calls
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;make&lt;/code&gt; function is a special built-in function used to allocate and initialize an object of type map, slice, or chan. For initializing a slice using &lt;code&gt;make&lt;/code&gt;, we have to supply the type of slice, the length of the slice, and the capacity of the slice as arguments. In the case of initializing a &lt;code&gt;map&lt;/code&gt; using &lt;code&gt;make&lt;/code&gt;, we need to pass the size of the &lt;code&gt;map&lt;/code&gt; as an argument.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;make&lt;/code&gt;, however, already has default values for those arguments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For channels, the buffer capacity defaults to zero (unbuffered).&lt;/li&gt;
&lt;li&gt;For maps, the size allocated defaults to a small starting size.&lt;/li&gt;
&lt;li&gt;For slices, the capacity defaults to the length if capacity is omitted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Therefore,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can be rewritten as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, using named constants with channels is not considered as an anti-pattern, for the purposes of debugging, or accommodating math, or platform-specific code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&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="c"&gt;// Not an anti-pattern&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Useless &lt;code&gt;return&lt;/code&gt; in functions
&lt;/h3&gt;

&lt;p&gt;It is not considered good practice to put a &lt;code&gt;return&lt;/code&gt; statement as the final statement in functions that do not have a value to return.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Useless return, not recommended&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;alwaysPrintFoofoo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foofoo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c"&gt;// Recommended&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;alwaysPrintFoo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foofoo"&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;Named returns should not be confused with useless returns, however. The return statement below really returns a value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;printAndReturnFoofoo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foofoo&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;foofoo&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"foofoo"&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foofoo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Useless &lt;code&gt;break&lt;/code&gt; statements in &lt;code&gt;switch&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In Go, &lt;code&gt;switch&lt;/code&gt; statements do not have automatic &lt;code&gt;fallthrough&lt;/code&gt;. In programming languages like C, the execution falls into the next case if the previous case lacks the &lt;code&gt;break&lt;/code&gt; statement. But, it is commonly found that &lt;code&gt;fallthrough&lt;/code&gt; in &lt;code&gt;switch&lt;/code&gt;-case is used very rarely and mostly causes bugs. Thus, many modern programming languages, including Go, changed this logic to never &lt;code&gt;fallthrough&lt;/code&gt; the cases by default.&lt;/p&gt;

&lt;p&gt;Therefore, it is not required to have a &lt;code&gt;break&lt;/code&gt; statement as the final statement in a case block of &lt;code&gt;switch&lt;/code&gt; statements. Both the examples below act the same.&lt;/p&gt;

&lt;p&gt;Bad pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"case one"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"case two"&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;Good pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"case one"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"case two"&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;However, for implementing &lt;code&gt;fallthrough&lt;/code&gt; in &lt;code&gt;switch&lt;/code&gt; statements in Go, we can use the &lt;code&gt;fallthrough&lt;/code&gt; statement. As an example, the code snippet given below will print &lt;code&gt;23&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;fallthrough&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;fallthrough&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"3"&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;
  
  
  7. Not using helper functions for common tasks
&lt;/h3&gt;

&lt;p&gt;Certain functions, for a particular set of arguments, have shorthands that can be used instead to improve efficiency and better understanding/readability.&lt;/p&gt;

&lt;p&gt;For example, in Go, to wait for multiple goroutines to finish, we can use a &lt;code&gt;sync.WaitGroup&lt;/code&gt;. Instead of incrementing a &lt;code&gt;sync.WaitGroup&lt;/code&gt; counter by &lt;code&gt;1&lt;/code&gt; and then adding &lt;code&gt;-1&lt;/code&gt; to it in order to bring the value of the counter to &lt;code&gt;0&lt;/code&gt; and in order to signify that all the goroutines have been executed :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// ...some code&lt;/span&gt;
&lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is easier and more understandable to use &lt;code&gt;wg.Done()&lt;/code&gt; helper function which itself notifies the &lt;code&gt;sync.WaitGroup&lt;/code&gt; about the completion of all goroutines without our need to manually bring the counter to &lt;code&gt;0&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// ...some code&lt;/span&gt;
&lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8. Redundant &lt;code&gt;nil&lt;/code&gt; checks on slices
&lt;/h3&gt;

&lt;p&gt;The length of a &lt;code&gt;nil&lt;/code&gt; slice evaluates to zero. Hence, there is no need to check whether a slice is &lt;code&gt;nil&lt;/code&gt; or not, before calculating its length.&lt;/p&gt;

&lt;p&gt;For example, the &lt;code&gt;nil&lt;/code&gt; check below is not necessary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code could omit the &lt;code&gt;nil&lt;/code&gt; check as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9. Too complex function literals
&lt;/h3&gt;

&lt;p&gt;Function literals that only call a single function can be removed without making any other changes to the value of the inner function, as they are redundant. Instead, the inner function that is being called inside the outer function should be called.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&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;Can be simplified as:&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Using &lt;code&gt;select&lt;/code&gt; statement with a single case
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;select&lt;/code&gt; statement lets a goroutine wait on multiple communication operations. But, if there is only a single operation/case, we don’t actually require &lt;code&gt;select&lt;/code&gt; statement for that. A simple &lt;code&gt;send&lt;/code&gt; or &lt;code&gt;receive&lt;/code&gt; operation will help in that case. If we intend to handle the case to try a send or receive without blocking, it is recommended to add a &lt;code&gt;default&lt;/code&gt; case to make the &lt;code&gt;select&lt;/code&gt; statement non-blocking.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Bad pattern&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c"&gt;// Recommended&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;code&gt;default&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"default"&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;
  
  
  11. context.Context should be the first param of the function
&lt;/h3&gt;

&lt;p&gt;The context.Context should be the first parameter, typically named ctx. ctx should be a (very) common argument for many functions in a Go code, and since it’s logically better to put the common arguments at the first or the last of the arguments list. Why? It helps us to remember to include that argument due to a uniform pattern of its usage. In Go, as the variadic variables may only be the last in the list of arguments, it is hence advised to keep context.Context as the first parameter. Various projects like even Node.js have some conventions like error first callback. Thus, it’s a convention that context.Context should always be the first parameter of a function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Bad practice&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;badPatternFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="n"&gt;favContextKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="c"&gt;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Recommended&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;goodPatternFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="n"&gt;favContextKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;    
    &lt;span class="c"&gt;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When it comes to working in a team, reviewing other people’s code becomes important. DeepSource is an automated code review tool that manages the end-to-end code scanning process and automatically makes pull requests with fixes whenever new commits are pushed or new pull requests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://deepsource.io/docs/analyzer/go.html" rel="noopener noreferrer"&gt;Setting up DeepSource&lt;/a&gt; for Go is extremely easy. As soon as you have it set up, an initial scan will be performed on your entire codebase, find scope for improvements, fix them, and open pull requests for those changes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;go build&lt;/code&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Breaking builds, baseball bats, and the code quality DNA</title>
      <dc:creator>Saif Sadiq</dc:creator>
      <pubDate>Mon, 15 Mar 2021 13:07:43 +0000</pubDate>
      <link>https://dev.to/deepsource/breaking-builds-baseball-bats-and-the-code-quality-dna-278n</link>
      <guid>https://dev.to/deepsource/breaking-builds-baseball-bats-and-the-code-quality-dna-278n</guid>
      <description>&lt;p&gt;“What’s the biggest set of items in terms of tech debt. I can attack it, scope it into the code quality sprints and then start incrementally evolving” - Badri elaborated.&lt;/p&gt;

&lt;p&gt;In Good Code Podcast, we talk to experienced developers and technical leaders about the art and science of writing good code and building software. In episode 5, we talk to Badri Rajasekar, who has spent almost 20 years building software and is currently the founder and CEO of &lt;a href="https://jamm.app/en/download/" rel="noopener noreferrer"&gt;Jamm&lt;/a&gt; - a rapidly growing video collaboration app.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Microsoft executive who alarmed everyone with a baseball bat
&lt;/h3&gt;

&lt;p&gt;While speaking about code quality and code review processes, Badri shared an incident from his initial days at Microsoft, when somebody broke the Windows Build and had hundreds of developers waiting for it to get fixed. Soon enough, a Microsoft executive stormed into the office with a baseball bat shouting “Who broke the build?”&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%2Fu1nyzq4vj6inj7459d37.gif" 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%2Fu1nyzq4vj6inj7459d37.gif" alt="Alt Text" width="1024" height="1024"&gt;&lt;/a&gt;&lt;br&gt;
With this hilarious (not at the time 😅) incident, Badri expounded on how code quality reviews have evolved over the past decade. Earlier, with strongly typed languages and no automation in place, errors could easily become blunders. Today, with the introduction of automated code reviews, various tooling, microservices, the concept of nightlies, and continuous integrations, there’s much more tolerance for both errors and blunders.&lt;/p&gt;

&lt;p&gt;Quick Read: &lt;a href="https://deepsource.io/blog/code-review-best-practices/?utm_source=devto&amp;amp;utm_term=talkwithbadri&amp;amp;utm_campaign=contentdistribution" rel="noopener noreferrer"&gt;Code Review Best Practices&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The flip side:&lt;/strong&gt; With the flexibility that these modern processes offer, it becomes even more critical to be careful in order to ensure code quality at every step of the way.&lt;/p&gt;

&lt;p&gt;In Badri’s words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s just as possible for organizations in this era of continuous delivery to ship a lot of buggy code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;The takeaway:&lt;/strong&gt; It’s extremely important to be structured around automation testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Slow down today and move 10X faster tomorrow onwards
&lt;/h3&gt;

&lt;p&gt;While talking about how inexperienced developers or new startups that don’t bother about integration testing for the sake of quick deployments, end up accumulating a lot of tech debt before they realize it, Badri shared another example of a rapidly growing startup that couldn’t slow down, hence making the problem worse for itself every day.&lt;/p&gt;

&lt;p&gt;Badri’s advice for situations like this - get as organized as possible, and try to not fix everything in one shot.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Have a strong process around all of your basic unit tests. Integration tests have to pass before a pull request gets merged in. Eg. Don’t submit a PR until the integration tests have passed. Be firm - either the tests have to pass or if they’re not passing, you’ve got to fix the test.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The key is to introduce code quality into the DNA of the company and encourage everyone on the team to think of it as an integral part of the process, and not rely on QA teams or site reliability engineers. Badri also shared his insights on how to do this — introducing quality sprints, having regular performance checks, taking care of the meta-questions, and maintaining documentation.&lt;/p&gt;

&lt;p&gt;He spoke about his time at TokBox and how they used to manage the code quality. They used to have a unified framework for instrumenting everything from platform health to analytics. They also made it fun by introducing the “Load Time Lama” - a fanciful creature who encouraged everyone to take care of the loading times.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; Avoid premature optimization of architecture, as you’ll miss out on crucial problems that haven’t cropped up since you haven’t seen scale yet.&lt;/p&gt;

&lt;h3&gt;
  
  
  The similarity between pilots and programmers
&lt;/h3&gt;

&lt;p&gt;Badri drew an analogy between pilots and programmers while explaining how to steer through massive amounts of data. When flying an airplane, a pilot majorly looks at a couple of indicators — the airspeed indicator, altimeter, heading indicator, etc. And when one of such indicators indicates a warning, only then he delves deeper into the issues.&lt;/p&gt;

&lt;p&gt;Similarly, while having analytics and continuous testing are critical, developers should not get lost in the data that accumulates over time. The way out is to simply stick to the basics. Have a “four-metric dashboard” that defines the code quality benchmarks for a team.&lt;/p&gt;

&lt;p&gt;At the same time, practicing causality where you reverse engineer the issues, rather than looking at a sea of graphs, makes it easier to figure out causal patterns.&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%2Fl5ytqicea6hpacojjw88.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%2Fl5ytqicea6hpacojjw88.png" alt="Alt Text" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The conversation wrapped up with golden advice:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Golden Advice: Keep your architecture simple!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Badri advocated the KISS (keep it simple silly) principle when it comes to architectures. This improves scalability and helps with faster resolution of unforeseen problems, because these are easy to reason about.&lt;/p&gt;

&lt;p&gt;After a lot of anecdotes, jokes, advisements, and laughter, the chat concluded.&lt;/p&gt;

&lt;p&gt;Interested in listening to the entire conversation?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Listen to the podcast &lt;a href="https://open.spotify.com/episode/1wrB1CljTNfBl2tiv9HoMn" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stay tuned for the next episode of the Good Code Podcast!&lt;/p&gt;

</description>
      <category>codequality</category>
      <category>codereview</category>
      <category>technicaldebt</category>
      <category>automatedcodereview</category>
    </item>
    <item>
      <title>5 Common mistakes in Go</title>
      <dc:creator>Saif Sadiq</dc:creator>
      <pubDate>Mon, 08 Mar 2021 06:49:22 +0000</pubDate>
      <link>https://dev.to/deepsource/5-common-mistakes-in-go-3e37</link>
      <guid>https://dev.to/deepsource/5-common-mistakes-in-go-3e37</guid>
      <description>&lt;p&gt;Bug-risks are issues in code that can cause errors and breakages in production. A bug is a flaw in the code that produces undesired or incorrect results. Code often has bug-risks due to poor coding practices, lack of version control, miscommunication of requirements, unrealistic time schedules for development, and buggy third-party tools. In this post, let’s take a look at a few commonly seen bug-risks in Go.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Infinite recursive call
&lt;/h3&gt;

&lt;p&gt;A function that calls itself recursively needs to have an exit condition. Otherwise, it will recurse forever until the system runs out of memory.&lt;/p&gt;

&lt;p&gt;This issue can be caused by common mistakes such as forgetting to add an exit condition. It can also happen “on purpose.” Some languages have tail-call optimization, which makes certain infinite recursive calls safe to use. Tail-call optimization allows you to avoid allocating a new stack frame for a function because the calling function will return the value that it gets from the called function. The most common use is tail-recursion, where a recursive function written to take advantage of tail-call optimization can use constant stack space. Go, however, does not implement tail-call optimization, and you will eventually run out of memory. However, this problem doesn’t apply to spawning new goroutines.&lt;/p&gt;

&lt;p&gt;Recommended reading: &lt;a href="https://dave.cheney.net/2013/06/02/why-is-a-goroutines-stack-infinite" rel="noopener noreferrer"&gt;Why is a Goroutine’s stack infinite ?&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Assignment to &lt;code&gt;nil&lt;/code&gt; map
&lt;/h3&gt;

&lt;p&gt;A map needs to be initialized using the &lt;code&gt;make&lt;/code&gt; function (or a &lt;code&gt;map&lt;/code&gt; literal) before you can add any elements. A new, empty map value is made using the built-in function &lt;code&gt;make&lt;/code&gt;, which takes the &lt;code&gt;map&lt;/code&gt; type and an optional capacity hint as arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The initial capacity does not bound its size: maps grow to accommodate the number of items stored in them, with the exception of &lt;code&gt;nil&lt;/code&gt; maps. A &lt;code&gt;nil&lt;/code&gt; map is equivalent to an empty map except that no elements may be added.&lt;/p&gt;

&lt;p&gt;Bad pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;countedData&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;][]&lt;/span&gt;&lt;span class="n"&gt;ChartElement&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;countedData&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;][]&lt;/span&gt;&lt;span class="n"&gt;ChartElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recommended reading: &lt;a href="https://stackoverflow.com/questions/35379378/go-assignment-to-entry-in-nil-map?rq=1" rel="noopener noreferrer"&gt;Go: assignment to entry in nil map&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Method modifies receiver
&lt;/h3&gt;

&lt;p&gt;A method that modifies a non-pointer receiver value may have unwanted consequences. This is a bug risk because the method may change the value of the receiver inside the method, but it won’t reflect in the original value. To propagate the change, the receiver must be a pointer.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;vmethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vmethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%+v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Output: {num:1 key:0xc0000961e0 items:map[1:true]}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;num&lt;/code&gt; must be modified:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;vmethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vmethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%+v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Output: &amp;amp;{num:8 key:0xc00010a040 items:map[1:true]}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Possibly undesired value being used in goroutine
&lt;/h3&gt;

&lt;p&gt;Range variables in a loop are reused at each iteration; therefore, a goroutine created in a loop will point to the range variable from the upper scope. This way, the goroutine could use the variable with an undesired value.&lt;/p&gt;

&lt;p&gt;In the example below, the value of index and value used in the goroutine are from the outer scope. Because the goroutines run asynchronously, the value of index and value could be (and usually are) different from the intended value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;mySlice&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;mySlice&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Index: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&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;To overcome this problem, a local scope must be created, like in the example below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;mySlice&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;mySlice&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Index: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&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;Another way to handle this could be by passing the values as args to the goroutines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;mySlice&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;mySlice&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Index: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&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;Recommended reading: &lt;a href="https://golang.org/doc/faq#closures_and_goroutines" rel="noopener noreferrer"&gt;What happens with closures running as goroutines?&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Deferring &lt;code&gt;Close&lt;/code&gt; before checking for a possible error
&lt;/h3&gt;

&lt;p&gt;It’s a common pattern amongst Go developers, to &lt;code&gt;defer&lt;/code&gt; the &lt;code&gt;Close()&lt;/code&gt; method for a value that implements the &lt;code&gt;io.Closer&lt;/code&gt; interface. For example, when opening a file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/tmp/file.md"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this pattern is harmful for writable files because deferring a function call ignores its return value, and the &lt;code&gt;Close()&lt;/code&gt; method can return errors. For instance, if you wrote data to the file, it might have been cached in memory and not flushed to disk by the time you called &lt;code&gt;Close&lt;/code&gt;. This error should be explicitly handled.&lt;/p&gt;

&lt;p&gt;While you could go ahead without using &lt;code&gt;defer&lt;/code&gt; at all, you would need to remember to close the file everytime their job is done. A better way would be to &lt;code&gt;defer&lt;/code&gt; a wrapper function, like in the example below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/tmp/file.md"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;closeErr&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;closeErr&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;closeErr&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error occured while closing the file :"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;closeErr&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;span class="p"&gt;}()&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recommended reading: &lt;a href="https://www.joeshaw.org/dont-defer-close-on-writable-files/" rel="noopener noreferrer"&gt;Do not defer Close() on writable files&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When it comes to working in a team, reviewing other people’s code becomes important. &lt;a href="https://deepsource.io/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=contentdistribution&amp;amp;utm_term=gobugrisks" rel="noopener noreferrer"&gt;DeepSource&lt;/a&gt; is an &lt;a href="https://dzone.com/articles/automated-code-review-tools-for-developers-in-2021" rel="noopener noreferrer"&gt;automated code review tool&lt;/a&gt; that manages the end-to-end code scanning process and automatically makes pull requests with fixes whenever new commits are pushed or new pull requests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://deepsource.io/docs/analyzer/go.html?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=contentdistribution&amp;amp;utm_term=gobugrisks" rel="noopener noreferrer"&gt;Setting up DeepSource for Go&lt;/a&gt; is extremely easy. As soon as you have it set up, an initial scan will be performed on your entire codebase, find scope for improvements, fix them, and open PRs for those changes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;go build&lt;/code&gt;!&lt;/p&gt;

</description>
      <category>go</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Leveraging static code analysis in a Ruby CI pipeline</title>
      <dc:creator>Saif Sadiq</dc:creator>
      <pubDate>Tue, 02 Mar 2021 17:18:06 +0000</pubDate>
      <link>https://dev.to/deepsource/leveraging-static-code-analysis-in-a-ruby-ci-pipeline-31g3</link>
      <guid>https://dev.to/deepsource/leveraging-static-code-analysis-in-a-ruby-ci-pipeline-31g3</guid>
      <description>&lt;p&gt;Continuous integration, or CI, refers to the culture and the technologies that enable continuously merging features and bug fixes into the main branch of the codebase. Code changes are incorporated immediately after testing, rather than being bunched with other updates in a &lt;em&gt;waterfall&lt;/em&gt; release process.&lt;/p&gt;

&lt;p&gt;Similarly, continuous delivery, or CD, refers to automatically deploying the changed code to the target environment, such as pre-production branches to staging and master to production. CD picks up where CI left off, and as such, they often go hand in hand.&lt;/p&gt;

&lt;p&gt;Static code analysis typically falls under the CI aspect of a CI/CD pipeline. Taking the example of a small Ruby project, we’ll be setting up a CI workflow to analyze code quality using static analysis in the following areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consistency, with the widely adopted &lt;a href="https://rubystyle.guide" rel="noopener noreferrer"&gt;Ruby style guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Layout, such as unjust spacing or misaligned indentation.&lt;/li&gt;
&lt;li&gt;Linting, such as inadequate permissions or redundant operations.&lt;/li&gt;
&lt;li&gt;Security analysis, such as the use of unsafe methods.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Creating a sandbox
&lt;/h3&gt;

&lt;p&gt;Let’s make a fresh new directory for our adventure today. Initialize a Git repository in the folder and check it into GitHub as we’ll be using GitHub Workflows as our CI tool (more on this later).&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="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;mkdir&lt;/span&gt; &lt;span class="n"&gt;proj&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;proj&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;touch&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gitignore&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Setting up Ruby and Bundler
&lt;/h3&gt;

&lt;p&gt;You probably already have Ruby installed on your computer. But I find it best not to use pre-installed Ruby for a couple of reasons. Reason the first, it’s generally much older than the latest stable version, and you don’t want to miss out on Ruby’s newest features, do you? Reason the second, it’s relatively easy to break your system by installing, removing, or updating a critical package.&lt;/p&gt;

&lt;p&gt;Don’t fret; there’s a solution — &lt;a href="http://rvm.io" rel="noopener noreferrer"&gt;RVM&lt;/a&gt;. I won’t get into details of RVM here, but using it, you can install and manage several versions of Ruby on a system, keeping the system Ruby pristine.&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="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;rvm&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;rvm&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we set up &lt;a href="https://bundler.io" rel="noopener noreferrer"&gt;Bundler&lt;/a&gt;, a fantastic package manager for Ruby. We need it to keep track of our projects dependencies. It’s extremely straightforward to install.&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="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;bundler&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To ensure that our project gems remain localized to our project, we can set up Bundler to install Gems at a given path. Create a directory &lt;code&gt;.bundle/&lt;/code&gt; and a &lt;code&gt;config&lt;/code&gt; file within the directory with the following content.&lt;/p&gt;

&lt;p&gt;With this configuration, Bundler will install all gems inside a &lt;code&gt;.gems/&lt;/code&gt; folder inside the current project folder &lt;code&gt;proj/&lt;/code&gt;. Add both directories &lt;code&gt;.bundle/&lt;/code&gt; and &lt;code&gt;.gems/&lt;/code&gt; to your &lt;code&gt;.gitignore&lt;/code&gt; file so that they are not checked into VCS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting familiar with Rubocop
&lt;/h3&gt;

&lt;p&gt;For analyzing the code quality in all the areas we mentioned above, we will be using &lt;a href="https://rubocop.org" rel="noopener noreferrer"&gt;Rubocop&lt;/a&gt;, one of the finest linters available for Ruby. Rubocop comes with an extensive collection of rules, called ‘&lt;em&gt;cops&lt;/em&gt;’, organized in groups, called ‘&lt;em&gt;departments&lt;/em&gt;’, based on their functionality.&lt;/p&gt;

&lt;p&gt;To install, add the line to your Gemfile and run &lt;code&gt;bundle install&lt;/code&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;# frozen_string_literal: true source 'https://rubygems.org' git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } + gem 'rubocop', '~&amp;gt; 1.9', require: false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To list all the offences in any given file or directory, just pass the names as arguments to &lt;code&gt;rubocop&lt;/code&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="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;rubocop&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dir_name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rubocop is also capable of autocorrecting most of the errors it reports, which is incredibly helpful. To enable autocorrection, pass the &lt;code&gt;-a&lt;/code&gt; flag. Passing &lt;code&gt;-A&lt;/code&gt; uses a more aggressive auto-correct mode, which is not advisable unless you are sure of what you are doing.&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="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;rubocop&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dir_name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;# safe autocorrect, recommended&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;rubocop&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="no"&gt;A&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dir_name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;# unsafe autocorrect, not recommended&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will need to prepend &lt;code&gt;bundle exec&lt;/code&gt; to these commands if Rubocop is not globally installed.&lt;/p&gt;

&lt;h3&gt;
  
  
  The code
&lt;/h3&gt;

&lt;p&gt;Now we get to the fun part, scripting in Ruby. Take this script, for example. It takes a file name as an argument and prints said file’s content to STDOUT, very similar to the &lt;code&gt;cat&lt;/code&gt; command (hence the name).&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;# cat.rb&lt;/span&gt;
&lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is formatted poorly, violates many rules from the style guide, and even has a couple of gaping security flaws. We’ll fix those pretty soon but first, let’s do a preliminary scan with Rubocop and observe the output.&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="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="n"&gt;rubocop&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
&lt;span class="no"&gt;Inspecting&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;
&lt;span class="no"&gt;W&lt;/span&gt; &lt;span class="no"&gt;Offenses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Correctable&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Style&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;FrozenStringLiteralComment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Missing&lt;/span&gt; &lt;span class="n"&gt;frozen&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;literal&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="c1"&gt;# cat.rb&lt;/span&gt;
&lt;span class="o"&gt;^&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Security&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;The&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="no"&gt;Kernel&lt;/span&gt;&lt;span class="c1"&gt;#open is a serious security risk.&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;^^^^&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;W&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Correctable&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Lint&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;RedundantWithIndex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Remove&lt;/span&gt; &lt;span class="n"&gt;redundant&lt;/span&gt; &lt;span class="n"&gt;with_index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;^^^^^^^^^^&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Correctable&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Layout&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;SpaceBeforeBlockBraces&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Space&lt;/span&gt; &lt;span class="n"&gt;missing&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="p"&gt;{.&lt;/span&gt;
&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Correctable&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Layout&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;SpaceInsideBlockBraces&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Space&lt;/span&gt; &lt;span class="n"&gt;between&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;missing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;^^&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Correctable&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Style&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;BlockDelimiters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Avoid&lt;/span&gt; &lt;span class="n"&gt;using&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;multi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="n"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&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;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Correctable&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Layout&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;TrailingEmptyLines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Final&lt;/span&gt; &lt;span class="n"&gt;newline&lt;/span&gt; &lt;span class="n"&gt;missing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;inspected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="n"&gt;offenses&lt;/span&gt; &lt;span class="n"&gt;detected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="n"&gt;offenses&lt;/span&gt; &lt;span class="n"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;correctable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rubocop found 7 offenses, of which 6 it can correct automatically, labeled as &lt;code&gt;[Correctable]&lt;/code&gt; in the output above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pipeline
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Picking the infrastructure
&lt;/h3&gt;

&lt;p&gt;Choices abound when it comes to picking a CI/CD infrastructure provider. From &lt;a href="https://travis-ci.com" rel="noopener noreferrer"&gt;Travis CI&lt;/a&gt;, a darling of open-source developers, to &lt;a href="https://www.jenkins.io" rel="noopener noreferrer"&gt;Jenkins&lt;/a&gt;, the tool of choice for enterprise teams who’d rather self-host their customized solution, dev-ops engineers are spoilt for choice.&lt;/p&gt;

&lt;p&gt;But the simplest of these in my experience has been &lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;GitHub workflows&lt;/a&gt;, a GitHub-native solution allowing you to set up entire chains of jobs, described as YAML files, that can be initiated based on specific triggers. We can use them throughout the CI/CD pipeline, from running checks on PRs before merge to deploying the code after. There are hundreds of pre-built actions (many officially maintained) that take the effort out of setting up end-to-end pipelines.&lt;/p&gt;

&lt;p&gt;Naturally, we’ll be using GitHub workflows as our CI pipeline infrastructure. The end goal is to have linting as a check on our PRs and commits. Only PRs that pass the checks would be mergeable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding lint workflow
&lt;/h3&gt;

&lt;p&gt;Let’s see what the workflow file would look like in our case. Create a new directory &lt;code&gt;.github/&lt;/code&gt;, create another directory within this one named &lt;code&gt;workflows/&lt;/code&gt;, and in this directory, create a file named &lt;code&gt;lint.yml&lt;/code&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;# .github/workflows/lint.yml&lt;/span&gt;
&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="no"&gt;Lint&lt;/span&gt;

&lt;span class="ss"&gt;on:
 push:
 branches:
 &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;

&lt;span class="ss"&gt;jobs:
 lint:
 name: &lt;/span&gt;&lt;span class="no"&gt;Lint&lt;/span&gt;
 &lt;span class="n"&gt;runs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;on: &lt;/span&gt;&lt;span class="n"&gt;ubuntu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;latest&lt;/span&gt;
 &lt;span class="ss"&gt;steps:
 &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="ss"&gt;uses: &lt;/span&gt;&lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;checkout&lt;/span&gt;&lt;span class="vi"&gt;@v2&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="ss"&gt;uses: &lt;/span&gt;&lt;span class="n"&gt;ruby&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ruby&lt;/span&gt;&lt;span class="vi"&gt;@v1&lt;/span&gt;
 &lt;span class="ss"&gt;with:
 &lt;/span&gt;&lt;span class="n"&gt;ruby&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;version: &lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;
 &lt;span class="n"&gt;bundler&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;cache: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;# runs `bundle install`&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="ss"&gt;run: &lt;/span&gt;&lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="n"&gt;rubocop&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The lint workflow consists of a single job. The job is fired on every push event to the &lt;code&gt;master&lt;/code&gt; branch and performs three steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;actions/checkout&lt;/code&gt;: checks out the code repository&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ruby/setup-ruby&lt;/code&gt;:

&lt;ol&gt;
&lt;li&gt;sets up Ruby version 3.0 and the latest compatible version of Bundler&lt;/li&gt;
&lt;li&gt;uses Bundler to install all packages in the &lt;code&gt;Gemfile&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;run&lt;/code&gt;: runs Rubocop on the entire current working directory&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;Once the job completes, we get our outcome. In our case, it’s a big red cross. The workflow execution fails because Rubocop found issues in the code. The logs reveal the same message we had seen earlier, and lists offences identified by Rubocop.&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%2Fdeepsource.io%2Fimages%2Fblog%2Fstatic-analysis-ci-ruby%2Fruby-ci-1.jpeg" 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%2Fdeepsource.io%2Fimages%2Fblog%2Fstatic-analysis-ci-ruby%2Fruby-ci-1.jpeg" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;😢 We’ll get there, eventually.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fixing problems
&lt;/h3&gt;

&lt;p&gt;We want our check to pass. Nobody likes failing checks. Coming back to our local setup, let’s use Rubocop’s autofix feature to quickly resolve these issues. First, we should let Rubocop take care of the automatic stuff using the &lt;code&gt;-a&lt;/code&gt; flag.&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="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="n"&gt;rubocop&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
&lt;span class="no"&gt;Inspecting&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;
&lt;span class="no"&gt;W&lt;/span&gt; &lt;span class="no"&gt;Offenses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Correctable&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Style&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;FrozenStringLiteralComment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Missing&lt;/span&gt; &lt;span class="n"&gt;frozen&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;literal&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="c1"&gt;# cat.rb&lt;/span&gt;
&lt;span class="o"&gt;^&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Security&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;The&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="no"&gt;Kernel&lt;/span&gt;&lt;span class="c1"&gt;#open is a serious security risk.&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;^^^^&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Corrected&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Layout&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;ExtraSpacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Unnecessary&lt;/span&gt; &lt;span class="n"&gt;spacing&lt;/span&gt; &lt;span class="n"&gt;detected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_line&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;W&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Corrected&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Lint&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;RedundantWithIndex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Remove&lt;/span&gt; &lt;span class="n"&gt;redundant&lt;/span&gt; &lt;span class="n"&gt;with_index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;^^^^^^^^^^&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Corrected&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Layout&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;SpaceBeforeBlockBraces&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Space&lt;/span&gt; &lt;span class="n"&gt;missing&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="p"&gt;{.&lt;/span&gt;
&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Corrected&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Layout&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;SpaceInsideBlockBraces&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Space&lt;/span&gt; &lt;span class="n"&gt;between&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;missing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;^^&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Corrected&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Style&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;BlockDelimiters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Avoid&lt;/span&gt; &lt;span class="n"&gt;using&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;multi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="n"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&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;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Corrected&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Layout&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;TrailingEmptyLines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Final&lt;/span&gt; &lt;span class="n"&gt;newline&lt;/span&gt; &lt;span class="n"&gt;missing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;inspected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;offenses&lt;/span&gt; &lt;span class="n"&gt;detected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="n"&gt;offenses&lt;/span&gt; &lt;span class="n"&gt;corrected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;offense&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;corrected&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="sb"&gt;`rubocop -A`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rubocop solved most of the issues reported, including one issue introduced during the autofix process itself! With 6 of the 7 problems are already fixed, we’ve managed to shave off ~70% of our work with zero effort input.&lt;/p&gt;

&lt;p&gt;What’s left is one unsafe autofix and one security vulnerability that Rubocop cannot fix automatically. We can take care of those:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The frozen string literal comment is missing. That’s a reasonable thing to add to the file, so we’ll let Rubocop add it using the stronger autofix flag &lt;code&gt;-A&lt;/code&gt;.
&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="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="n"&gt;rubocop&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="no"&gt;A&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
&lt;span class="no"&gt;Inspecting&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;
&lt;span class="no"&gt;C&lt;/span&gt; &lt;span class="no"&gt;Offenses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Corrected&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Style&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;FrozenStringLiteralComment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Missing&lt;/span&gt; &lt;span class="n"&gt;frozen&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;literal&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="c1"&gt;# cat.rb&lt;/span&gt;
&lt;span class="o"&gt;^&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Corrected&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="no"&gt;Layout&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;EmptyLineAfterMagicComment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Add&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;empty&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;magic&lt;/span&gt; &lt;span class="n"&gt;comments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="c1"&gt;# cat.rb&lt;/span&gt;
&lt;span class="o"&gt;^&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&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="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Security&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;The&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="no"&gt;Kernel&lt;/span&gt;&lt;span class="c1"&gt;#open is a serious security risk.&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;^^^^&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;inspected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;offenses&lt;/span&gt; &lt;span class="n"&gt;detected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;offenses&lt;/span&gt; &lt;span class="n"&gt;corrected&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit and push. We’re green now! At this point, you should pat yourself on the back for a job well done.&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%2Fdeepsource.io%2Fimages%2Fblog%2Fstatic-analysis-ci-ruby%2Fruby-ci-2.jpeg" 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%2Fdeepsource.io%2Fimages%2Fblog%2Fstatic-analysis-ci-ruby%2Fruby-ci-2.jpeg" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🥳 Yay!&lt;/p&gt;

&lt;h3&gt;
  
  
  Staying clean
&lt;/h3&gt;

&lt;p&gt;Now that you’re at peak code quality, we need to ensure it stays that way. This means that we need to ensure that no PR negatively affects our codebase quality. To run the check on every incoming PR, add the &lt;code&gt;pull_request&lt;/code&gt; event to our lint workflow.&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="ss"&gt;on: on: push: branches: &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="ss"&gt;pull_request:
&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="ss"&gt;branches:
&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, to test that our check is working as expected, we need to make a PR with some code that Rubocop would flag. Let’s refactor the lines in our script, that are concerned with reading the file, to use a block.&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;# cat.rb # frozen_string_literal: true filename = ARGV[0] - file = File.open(filename)&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_line&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check out a new branch from &lt;code&gt;master&lt;/code&gt;. Commit and push to this branch and open a PR. You’ll see that the checks fail, and thus the PR cannot be merged unless overridden by an administrator.&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%2Fdeepsource.io%2Fimages%2Fblog%2Fstatic-analysis-ci-ruby%2Fruby-ci-3.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%2Fdeepsource.io%2Fimages%2Fblog%2Fstatic-analysis-ci-ruby%2Fruby-ci-3.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚧 Our check is working just fine!&lt;/p&gt;

&lt;p&gt;🧠 &lt;strong&gt;Brain-teaser:&lt;/strong&gt; Can you identify why the updated code, using a block, is being flagged by Rubocop?&lt;/p&gt;

&lt;p&gt;🤷‍♂️ &lt;strong&gt;Hint:&lt;/strong&gt; If you want a hint, here’s the Rubocop output for the PR:&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="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="n"&gt;rubocop&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
&lt;span class="no"&gt;Inspecting&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;
&lt;span class="no"&gt;W&lt;/span&gt;

&lt;span class="no"&gt;Offenses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;7&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="no"&gt;W&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Lint&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="no"&gt;UselessAssignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Useless&lt;/span&gt; &lt;span class="n"&gt;assignment&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;variable&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
  &lt;span class="nf"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;
  &lt;span class="o"&gt;^^^^&lt;/span&gt;

&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;inspected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;offense&lt;/span&gt; &lt;span class="n"&gt;detected&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧑‍💻 &lt;strong&gt;Answer:&lt;/strong&gt; Defining &lt;code&gt;list&lt;/code&gt; inside the block means that it is not accessible outside the block. This makes the assignment useless and will lead to a bug in the subsequent use of the variable.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Lesson:&lt;/strong&gt; Though indirectly, code analysis can sometimes also help identify potential bugs!&lt;/p&gt;

&lt;h2&gt;
  
  
  DeepSource
&lt;/h2&gt;

&lt;p&gt;While we invested considerable time and effort, we now have checks and actions set up to monitor code quality in our repo. But what if we didn’t have time to spare or didn’t want to spend the effort? We’re busy developers, after all!&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%2Fbojddazgf4gnjex4nq5j.gif" 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%2Fbojddazgf4gnjex4nq5j.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consider using &lt;a href="https://deepsource.io/" rel="noopener noreferrer"&gt;DeepSource&lt;/a&gt;. It continuously scans the code on every commit, and on every pull request, through various static code analyzers (including linters and security analyzers), and can automatically fix some of them. DeepSource also has its custom-built analyzers for most languages that are constantly improved and kept up-to-date.&lt;/p&gt;

&lt;p&gt;It’s &lt;a href="https://deepsource.io/docs/analyzer/ruby.html" rel="noopener noreferrer"&gt;incredibly easy to set up&lt;/a&gt;! You need only add a &lt;code&gt;.deepsource.toml&lt;/code&gt; file in your repository root, and DeepSource will pick it up. It takes much less effort and the end result is way more polished that setting up several workflows in GitHub.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version = 1

[[analyzers]]
name = "ruby"
enabled = true

[[transformers]]
name = "rubocop"
enabled = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Automate the tedium away
&lt;/h2&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%2Fwjiglypq97hdnjnfs8bh.gif" 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%2Fwjiglypq97hdnjnfs8bh.gif" width="498" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CI/CD pipelines are quintessential to the agile development workflow. The ability to add features, squash bugs, and get the changes in production instantly can make a very significant difference. Startups live or die based on how often they iterate.&lt;/p&gt;

&lt;p&gt;Integrating static analysis into the CI pipeline ensures that only the cleanest and most compliant code makes its way into production. For something that takes very little time to set up, consumes a minuscule amount of resources, and does not significantly affect test/build timings, static analysis can add a lot of confidence to your build process.&lt;/p&gt;

&lt;p&gt;Confident iterations await. Till next time!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Automate code formatting in Python</title>
      <dc:creator>Saif Sadiq</dc:creator>
      <pubDate>Tue, 16 Feb 2021 08:06:53 +0000</pubDate>
      <link>https://dev.to/deepsource/automate-code-formatting-in-python-4d23</link>
      <guid>https://dev.to/deepsource/automate-code-formatting-in-python-4d23</guid>
      <description>&lt;p&gt;Right off the bat, let’s clarify an important distinction. Writing code that works and writing good code are two very different things. The former is a skill while the latter is an art form, and this difference distinguishes great programmers from the crowd.&lt;/p&gt;

&lt;p&gt;When we talk of good code, the word ‘good’ is vague by design. That’s because there are no rules set in stone about what makes code good or bad. All we have are some abstract guidelines such as readability:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Programs are meant to be read by humans and only incidentally for computers to execute.&lt;/p&gt;

&lt;p&gt;– Abelson &amp;amp; Sussman&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those are two MIT professors with pretty solid credentials. Identifying the quality of code is an intuition that is honed over time, through practice and experience. Code reviews go a long way towards this goal.&lt;/p&gt;

&lt;p&gt;Code review is the process where developers more experienced than yourself read through your code and suggest improvements that could make it better. These suggestions can improve performance, incorporate new language features, patch security oversights, or correct code style.&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%2Fdyfspzf4n5yntzulqnj3.gif" 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%2Fdyfspzf4n5yntzulqnj3.gif" alt="Alt Text" width="498" height="206"&gt;&lt;/a&gt;&lt;em&gt;... when it comes to code review.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But manual code reviews are expensive. The time it takes someone to read your code is time they did not spend building awesome stuff. They are also error-prone and by no means comprehensive. There are human limits to knowledge and memory.&lt;br&gt;&lt;br&gt;
Enter automation. Automated code reviews are faster, less error-prone, and more in-depth than their manual counterparts.&lt;/p&gt;

&lt;p&gt;Let’s dive deep into the process with a sample project containing a single Python file. We’ll riddle the file with issues and then set up a workflow that automatically finds and fixes these problems.&lt;/p&gt;
&lt;h2&gt;
  
  
  Ingredients
&lt;/h2&gt;
&lt;h3&gt;
  
  
  A. Codebase with PEP-8 violations
&lt;/h3&gt;

&lt;p&gt;Before we automate code review, let’s first write some code to review. Here is a sample program that lists primes up to a given number. It might hurt to look at, which is good as it means your code-olfactory senses are working.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# list_primes.py
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_prime&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_primes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;is_prime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;F&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is prime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;list_primes&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are a lot of problems with this script. Don’t get me wrong, it works, but it’s not good.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extraneous space before function parenthesis&lt;/li&gt;
&lt;li&gt;2-space indentation&lt;/li&gt;
&lt;li&gt;No spaces around operators&lt;/li&gt;
&lt;li&gt;Single line around functions&lt;/li&gt;
&lt;li&gt;Uppercase &lt;code&gt;F&lt;/code&gt; in f-strings&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  B. Black code formatter
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://black.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;Black&lt;/a&gt; is a popular code formatter for Python. It is capable of automatically reformatting your Python files, fixing all code style violations. What’s neat is that it is pretty opinionated and can’t be configured much, making it ideal for automation.&lt;/p&gt;

&lt;p&gt;So let’s install Black, while also taking the opportunity to set up some first-class dependency management with a tool I personally love, &lt;a href="https://pipenv.pypa.io/en/latest/" rel="noopener noreferrer"&gt;Pipenv&lt;/a&gt;. Running the following command creates two files, &lt;code&gt;Pipfile&lt;/code&gt; and &lt;code&gt;Pipfile.lock&lt;/code&gt;, in the root of the repo and installs Black as a dev dependency.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;pipenv&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;pre&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;black&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running Black without any args formats all files in the repo directly. Apart from reformatting your files, it has two less dangerous modes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--check&lt;/code&gt;: In this mode, Black purely checks if there are any code style violations. The return code is 0 if there are no violations and non-zero if there are any.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;pipenv&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;black&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;check&lt;/span&gt; &lt;span class="n"&gt;list_primes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;would&lt;/span&gt; &lt;span class="n"&gt;reformat&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dhruvkb&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Documents&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;scratch&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;automata&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;list_primes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;Oh&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt; &lt;span class="err"&gt;💥&lt;/span&gt; &lt;span class="err"&gt;💔&lt;/span&gt; &lt;span class="err"&gt;💥&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="n"&gt;would&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;reformatted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;--diff&lt;/code&gt;: In this mode, Black shows the changes it will make without actually making them. This mode is helpful if you want to inspect the changes before they are actually made.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;pipenv&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;black&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="n"&gt;list_primes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt; &lt;span class="n"&gt;list_primes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;  &lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;00.000000&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;0000&lt;/span&gt;
&lt;span class="o"&gt;+++&lt;/span&gt; &lt;span class="n"&gt;list_primes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;  &lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;00.000000&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;0000&lt;/span&gt;
&lt;span class="o"&gt;@@&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="mi"&gt;17&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="mi"&gt;19&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt;
 &lt;span class="c1"&gt;# list_primes.py
&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_prime&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_prime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;
 &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_primes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&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="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;is_prime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;F&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is prime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is prime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;

 &lt;span class="nf"&gt;list_primes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Recipe
&lt;/h2&gt;

&lt;p&gt;Code review can be split in two parts: the interesting part where you solve big picture issues and the mundane parts where you identify non-idiomatic snippets and code style violations. Let’s automate the boring parts of the code review.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Set up Git hooks
&lt;/h3&gt;

&lt;p&gt;We just saw how incredible Black is. Wouldn’t it be awesome if Black ran automatically every time you were to commit your code? It’s possible, with Git hooks. Git hooks are programs that run on your codebase when you execute certain Git commands. The ‘pre-commit’ hook is of particular interest to us because we’d like the lint check to take place before the commit is created, and prevent the commit from being created if it fails.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/greenbone/autohooks" rel="noopener noreferrer"&gt;Autohooks&lt;/a&gt; is a Python package for managing these hooks via Python. It has a plugin system that enables integration with tools like Black. Let’s install both Autohooks and the Black-integration plugin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pipenv install --dev autohooks autohooks-plugin-black
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make a &lt;code&gt;pyproject.toml&lt;/code&gt; file in the root of your repo with the following content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;autohooks&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pipenv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;pre&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;autohooks.plugins.black&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;autohooks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;black&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;arguments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--check&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Activate the hooks and run the check function to see if everything works fine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pipenv run autohooks activate
✓ autohooks pre-commit hook installed at /Users/hal/Documents/scratch/.git/hooks/pre-commit using pipenv mode.

$ pipenv run autohooks check
✓ autohooks pre-commit hook is active.
✓ autohooks pre-commit hook is up-to-date.
ℹ Using autohooks mode "pipenv".
✓ Plugin "autohooks.plugins.black" active and loadable.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try &lt;code&gt;git commit&lt;/code&gt;-ing the poorly written source code. Ha, gotcha! Here’s how things will go down:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The pre-commit hook will be initiated.&lt;/li&gt;
&lt;li&gt;The top-level hooks by Autohooks will be invoked.&lt;/li&gt;
&lt;li&gt;Autohooks will then execute Black with the &lt;code&gt;--check&lt;/code&gt; argument.&lt;/li&gt;
&lt;li&gt;Black will return a non-zero code because the file contains errors.&lt;/li&gt;
&lt;li&gt;Git will halt the commit operation.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git add . &amp;amp;&amp;amp; git commit -m "Add the source code to VCS"
ℹ autohooks =&amp;gt; pre-commit
ℹ Running autohooks.plugins.black
would reformat /Users/dhruvkb/Documents/scratch/automata/list_primes.py
Oh no! 💥 💔 💥
1 file would be reformatted.
×
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡 &lt;strong&gt;Pro-tip:&lt;/strong&gt; You can bypass the hook with the &lt;code&gt;--no-verify&lt;/code&gt; flag on &lt;code&gt;git commit&lt;/code&gt;. It’s not recommended but we’re not the police, so do what you want.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡 Pro-tip:&lt;/strong&gt; You can remove the &lt;code&gt;--check&lt;/code&gt; argument and then every time you commit, Black will reformat your files for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Lint check using GitHub Actions
&lt;/h3&gt;

&lt;p&gt;The main drawback of Git hooks is that they are local. In a project with multiple contributors, there might be people who might forget to activate the hook or actively try to bypass them. In such cases, the solution is to run the lint check on the remote repo itself. GitHub Actions provides an extremely versatile solution for running the lint.&lt;/p&gt;

&lt;p&gt;Create the file &lt;code&gt;lint.yml&lt;/code&gt; inside the &lt;code&gt;.github/workflows&lt;/code&gt; directory of the repo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/lint.yml
&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Lint&lt;/span&gt;

&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pull_request&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="n"&gt;lint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="n"&gt;runs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ubuntu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;latest&lt;/span&gt;
 &lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;checkout&lt;/span&gt;&lt;span class="nd"&gt;@v2&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="nd"&gt;@v2&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;psf&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;black&lt;/span&gt;&lt;span class="nd"&gt;@stable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This workflow checks out the repository, sets up Python, installs Black and then lints the files. By default, this action runs Black with the &lt;code&gt;--check&lt;/code&gt; and &lt;code&gt;--diff&lt;/code&gt; arguments. Once you set up linting, all future commits and PRs will pass through Black.&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%2Fiwn9qq4g8q4n8jnmxyml.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%2Fiwn9qq4g8q4n8jnmxyml.png" alt="Alt Text" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;list_primes.py&lt;/code&gt; file will fail the test. The logs will show both the failing files as well as the diffs for those files (because of the &lt;code&gt;-diff&lt;/code&gt; argument). That’ll come in pretty handy when you’re fixing the violations.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Lint fixes using GitHub Workflows
&lt;/h3&gt;

&lt;p&gt;That brings us to the one aspect we still haven’t addressed yet. Black is capable of reformatting files, but so far, we have only used it to detect issues and present diffs. We’ve not tapped into Black’s full potential yet.&lt;/p&gt;

&lt;p&gt;How about we turn the automation up to 11 and update our GitHub workflow to automatically fix code style violations?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/lint.yml
&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Lint&lt;/span&gt;

&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;push&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;workflow_dispatch&lt;/span&gt;

&lt;span class="n"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="n"&gt;lint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="n"&gt;runs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ubuntu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;latest&lt;/span&gt;
 &lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;checkout&lt;/span&gt;&lt;span class="nd"&gt;@v2&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="nd"&gt;@v2&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Install&lt;/span&gt; &lt;span class="n"&gt;Python&lt;/span&gt; &lt;span class="n"&gt;dependencies&lt;/span&gt;
 &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;pipenv&lt;/span&gt;
 &lt;span class="n"&gt;pipenv&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;deploy&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;system&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;wearerequired&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lint&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="nd"&gt;@v1&lt;/span&gt;
 &lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="n"&gt;github_token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GITHUB_TOKEN&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
 &lt;span class="n"&gt;black&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
 &lt;span class="n"&gt;auto_fix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This workflow uses the same two steps as the previous one, that is checking out the repo and setting up Python. Then we install Pipenv and use that to install Black on the system. The &lt;code&gt;lint-action&lt;/code&gt; &lt;a href="https://github.com/wearerequired/lint-action" rel="noopener noreferrer"&gt;action&lt;/a&gt; runs Black and then commits the changed files. This creates a new commit with the same changes that Black had shown in the diff!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡 Pro-tip:&lt;/strong&gt; You can customize the author’s name and email and also the message of the commit. Just add the following to the &lt;code&gt;with&lt;/code&gt; key of the action. It’s an opportunity to be creative!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;commit_message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Opening the pod-bay doors&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;git_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;HAL-9000&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;git_email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;hal@hal.hal&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fecmm8rldruluykofyej5.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%2Fecmm8rldruluykofyej5.png" alt="Alt Text" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you can be assured that code pushed to the repo is free from style guide deviations, this frees up code reviewers to take a bigger picture look at the code and leave the minutiae to HAL.&lt;/p&gt;

&lt;h2&gt;
  
  
  End-to-end automation with DeepSource
&lt;/h2&gt;

&lt;p&gt;Phew! That was a lot of work, wasn’t it? But guess what, we only looked at style guide violations for now. Adding more features like looking for security gaps, finding possible bugs, and making complex refactors would make this a very long exercise. But it does not have to be.&lt;/p&gt;

&lt;p&gt;You could also consider automating this entire audit, review and refactor process with &lt;a href="https://deepsource.io/python-static-code-analysis/" rel="noopener noreferrer"&gt;DeepSource&lt;/a&gt; that can scan your code on every commit, and for every pull request, through several tools (including linters and security analyzers) and can automatically fix many issues. DeepSource also has its custom-built analyzers for most languages that are constantly improved and kept up-to-date.&lt;/p&gt;

&lt;p&gt;It’s &lt;a href="https://deepsource.io/docs/analyzer/python.html" rel="noopener noreferrer"&gt;incredibly easy to set up&lt;/a&gt;! You need only add a &lt;code&gt;.deepsource.toml&lt;/code&gt; file in your repository root, and DeepSource will pick it up. Much less effort than what we just went through.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version = 1

[[analyzers]]
name = "python"
enabled = true

  [analyzers.meta]
  runtime_version = "3.x.x"
  max_line_length = 80

[[transformers]]
name = "black"
enabled = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Finis coronat opus
&lt;/h2&gt;

&lt;p&gt;Code reviews are a very important learning tool for new developers. It’s a way to transfer knowledge, experience, and convention from a senior developer to a junior, a way to understand how even the code that was deemed as final can be made better, cleaner, and more efficient.&lt;/p&gt;

&lt;p&gt;I’d venture so far as to say that code reviews are one of the best learning tools for developers, and they are wasted on mundane things like code style. Introduce a little automation and make every code review count.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;They know enough who know how to learn.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When done well, a code review can be a truly educational experience. Automation cannot replace that. What automation can do is take the mundane out of the process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://deepsource.io/blog/code-review-best-practices/" rel="noopener noreferrer"&gt;Here’s to better code reviews!&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Common Python security pitfalls, and how to avoid them</title>
      <dc:creator>Saif Sadiq</dc:creator>
      <pubDate>Wed, 10 Feb 2021 17:43:05 +0000</pubDate>
      <link>https://dev.to/deepsource/common-python-security-pitfalls-and-how-to-avoid-them-50gh</link>
      <guid>https://dev.to/deepsource/common-python-security-pitfalls-and-how-to-avoid-them-50gh</guid>
      <description>&lt;p&gt;Python is undoubtedly a popular language. It consistently ranks among the most popular and most loved languages &lt;a href="https://insights.stackoverflow.com/survey/2019" rel="noopener noreferrer"&gt;year&lt;/a&gt; after &lt;a href="https://insights.stackoverflow.com/survey/2018" rel="noopener noreferrer"&gt;year&lt;/a&gt;. That’s not hard to explain, considering how fluent and expressive it is. Its pseudocode-like syntax makes it extremely easy for beginners to pick it up as their first language, while its vast library of packages (including the likes of giants like Django and TensorFlow) ensure that it scales up for any task required of it.&lt;/p&gt;

&lt;p&gt;Being such a widely-used language makes Python a very attractive target for malicious hackers. Let’s see a few simple ways to secure your Python apps and keep the black-hats at bay.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems and solutions
&lt;/h2&gt;

&lt;p&gt;Python places a lot of importance on zen, or developer happiness. The clearest evidence of that lies in the fact that the guiding principles of Python are summarized in a poem. Try &lt;code&gt;import this&lt;/code&gt; in a Python shell to read it. Here are some security concerns that might disturb your zen, along with solutions to restore it to a state of calm.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unsafe deserialization
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://owasp.org/www-project-top-ten/" rel="noopener noreferrer"&gt;OWASP Top Ten&lt;/a&gt;, a basic checklist for web security, mentions unsafe deserialization as one of the ten most common security flaws. While it’s common knowledge that executing anything coming from the user is a terrible idea, serializing and deserializing user input does not seem equally serious. After all, no code is being run, right? Wrong,&lt;/p&gt;

&lt;p&gt;PyYAML is the &lt;em&gt;de-facto&lt;/em&gt; standard for YAML serialization and deserialization in Python. The library supports serializing custom data types to YAML and deserializing them back to Python objects. See this serialization code here and the YAML produced by it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# serialize.py
import yaml class Person: def __init__ (self, name, age): self.name = name self.age = age def __str__ (self): return f'&amp;lt;Person: {self.name} - {self.age}&amp;gt;' def __repr__ (self): return str(self) person = Person('Dhruv', 24)
with open('person.yml', 'w') as output_file: yaml.dump(person, output_file)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;!!python/object: __main__.Person
age: 24
name: Dhruv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deserializing this YAML gives back the original data type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# deserialize.py
import yaml # class Person needs to be present in the scope
with open('person.yml', 'r') as input_file: person = yaml.load(input_file, Loader = yaml.Loader) print(person)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python deserialize.py ↵
&amp;lt;Person: Dhruv - 24&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the line &lt;code&gt;!!python/object: __main__.Person&lt;/code&gt; in the YAML describes how to re-instantiate objects from their text representations. But this opens up a &lt;a href="https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load%28input%29-Deprecation" rel="noopener noreferrer"&gt;slew of attack vectors, that can escalate to RCE&lt;/a&gt; when this instantiation can execute code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The solution, as trivial as it may seem, is to use safe-loading by swapping out the loader &lt;code&gt;yaml.Loader&lt;/code&gt; in favor of the &lt;code&gt;yaml.SafeLoader&lt;/code&gt; loader. This loader is safer because it completely blocks loading of custom classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# deserialize.py
import yaml # class Person needs to be present in the scope
with open('person.yml', 'r') as input_file: person = yaml.load(input_file, Loader = yaml.SafeLoader) print(person)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python deserialize.py ↵
ConstructorError: could not determine a constructor for the tag 'tag:yaml.org,2002:python/object: __main__.Person'
  in "person.yml", line 1, column 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Standard types like hashes and arrays can still be serialized to and deserialized from YAML documents just like before. Most people, probably including you, won’t even realize the difference.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;age: 24
name: Dhruv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python deserialize.py ↵
{'age': 24, 'name': 'Dhruv'}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dynamic execution
&lt;/h3&gt;

&lt;p&gt;Python has a pair of very dangerous functions: &lt;code&gt;exec&lt;/code&gt; and &lt;code&gt;eval&lt;/code&gt;. Both are very similar in terms of what they do: process the strings passed to them as Python code. &lt;code&gt;exec&lt;/code&gt; expects the string to be a statement, which it will execute and not return a value. &lt;code&gt;eval&lt;/code&gt; expects the string to be an expression and will return the computed value of the expression.&lt;/p&gt;

&lt;p&gt;Here is an example of what both these functions in action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eval('2 + 5') # returns 7
exec('print("Hello")') # prints "Hello", no return
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could in theory, pass a statement to &lt;code&gt;eval&lt;/code&gt; and get a similar effect as &lt;code&gt;exec&lt;/code&gt;, because in Python returning &lt;code&gt;None&lt;/code&gt; is virtually the same as not returning anything at all.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eval('print("Hello")') # prints "Hello", returns None
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The danger of these functions lies in the ability of these functions to execute virtually any code in the same Python process. Passing any input to the function that you cannot be 100% certain about, is akin to handing over your server keys to malicious hackers on a plate. This is the very definition of RCE.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are ways to mitigate the access that eval has. You can restrict access to globals and locals by passing dictionaries as the second and third arguments to &lt;code&gt;eval&lt;/code&gt; respectively. Remember that locals take priority over globals in case of conflict.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x = 3
eval('x + 5') # returns 8
eval('x + 5', { 'x': 2 }) # returns 7
eval('x + 5', { 'x': 2 }, { 'x': 1 }) # returns 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That makes the code safer yes. At least it somewhat prevents the data in the variables from being leaked.&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%2F9byl34355rwi5w61nqwj.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%2F9byl34355rwi5w61nqwj.png" width="538" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But it still doesn’t prevent the string from accessing any built-ins like &lt;code&gt;pow&lt;/code&gt;, or more dangerously, &lt;code&gt;__import__&lt;/code&gt;. To counter that, you need to override &lt;code&gt;__builtins__&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eval(" __import__ ('math').sqrt(5)", {}, {}) # returns 2.2360679774997898
eval( " __import__ ('math').sqrt(5)", { " __builtins__": None }, {} # restricts access to built-ins
) # error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Safe to expose now? Not quite. Because regardless of how secure you make &lt;code&gt;eval&lt;/code&gt;, it’s job is to evaluate an expression and nothing can stop the expression from taking too long and freezing the server for a long time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eval("2 ** 2147483647", { " __builtins__": None }, {}) # goodbye!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we Python developers like to say, “&lt;code&gt;eval&lt;/code&gt; &lt;strong&gt;is evil&lt;/strong&gt;.”&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependency management
&lt;/h3&gt;

&lt;p&gt;Python’s popularity draws the attention of white-hat security researchers just as much as it does that of hackers with malicious intent. As a result, new security vulnerabilities that are constantly discovered, disclosed, and patched. To keep the malicious hackers at bay, your software needs to keep all its dependencies up to date.&lt;/p&gt;

&lt;p&gt;A common technique for pinning packages in Python is the ubiquitous &lt;code&gt;requirements.txt&lt;/code&gt; file, a simple file that lists all the dependencies and exact versions needed by your project.&lt;/p&gt;

&lt;p&gt;Let’s say you install Django. As of writing, Django depends on three more packages. If you freeze your dependencies, you end up with the following requirements. Note that only one of these dependencies was installed by you, the other 3 are sub-dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pip freeze ↵
asgiref==3.3.1
Django==3.1.5
pytz==2020.5
sqlparse==0.4.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;pip freeze&lt;/code&gt; does not place dependencies in levels and that’s a problem. For smaller projects with a few dependencies that you can keep a track of mentally, this is not a big deal but as your projects grow, so will your top level dependencies. Conflicts arise when sub-dependencies overlap. Updating individual dependencies is a mess too, because the graph relationship of these dependencies is not clear from the plain text file.&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%2Fla8p9alg8ifyrvu5el0l.jpg" 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%2Fla8p9alg8ifyrvu5el0l.jpg" width="500" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pipenv.pypa.io/en/latest/" rel="noopener noreferrer"&gt;Pipenv&lt;/a&gt; and &lt;a href="https://python-poetry.org" rel="noopener noreferrer"&gt;Poetry&lt;/a&gt; are two tools that help you manage dependencies better. I prefer Pipenv but Poetry is equally good. Both package managers build on top of &lt;code&gt;pip&lt;/code&gt;. &lt;strong&gt;Fun fact:&lt;/strong&gt; DeepSource is compatible with both Pipenv and Poetry as package managers.&lt;/p&gt;

&lt;p&gt;Pipenv, for example, tracks your top-level dependencies in a &lt;code&gt;Pipfile&lt;/code&gt; and then does the hard work of locking down dependencies in a lockfile name &lt;code&gt;Pipfile.lock&lt;/code&gt;, similar to how &lt;code&gt;npm&lt;/code&gt; manages Node.js packages. Here’s an example &lt;code&gt;Pipfile&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
django = "*"

[requires]
python_version = "3.9"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, you can get a clear picture of the top-level dependencies of your app. Updating dependencies is also much easier because you just need to update the top level packages and the locking algorithm will figure out the most compatible and up-to-date versions of all the sub-dependencies.&lt;/p&gt;

&lt;p&gt;Here is the same example with Django. Notice how Pipenv can identify your top-level dependencies and its dependencies and so on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pipenv graph ↵
Django==3.1.5
  - asgiref [required: &amp;gt;=3.2.10,&amp;lt;4, installed: 3.3.1]
  - pytz [required: Any, installed: 2020.5]
  - sqlparse [required: &amp;gt;=0.2.2, installed: 0.4.1]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your code is hosted on GitHub, make sure you turn on and configure &lt;a href="https://dependabot.com" rel="noopener noreferrer"&gt;Dependabot&lt;/a&gt; as well. It’s a nifty little bot that alerts you if any of your dependencies has gone out of date or if a vulnerability has been identified in the pinned version of a dependency. Dependabot will also make PRs to your repo, automatically updating your packages. Very handy indeed!&lt;/p&gt;

&lt;h3&gt;
  
  
  Runtime assertions
&lt;/h3&gt;

&lt;p&gt;Python has a special &lt;code&gt;assert&lt;/code&gt; keyword for guarding against unexpected situations. The purpose of &lt;code&gt;assert&lt;/code&gt; is simple, verify a condition and raise an error if the condition is not fulfilled. In essence, &lt;code&gt;assert&lt;/code&gt; evaluates the given expression and&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if it evaluates to a truthy value, moves along&lt;/li&gt;
&lt;li&gt;if it evaluates to a falsey value, raises an &lt;code&gt;AssertionError&lt;/code&gt; with the given message&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consider this example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def do_something_dangerous(user, command): assert user.has_permissions(command), f'{user} is not authorized' user.execute(command)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a very simple example where we check if the user has the permissions to perform an action and subsequently perform the given action. In this case, if &lt;code&gt;user.has_permissions()&lt;/code&gt; returns &lt;code&gt;False&lt;/code&gt;, our assertion would cause an &lt;code&gt;AssertionError&lt;/code&gt; and the execution would be halted. Seems pretty safe, right?&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%2Fiw5bmyi843t1zdoj70pb.gif" 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%2Fiw5bmyi843t1zdoj70pb.gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No. Assertions are tools for developers during development and debugging phases. Asserts should not be used to guard critical functionality. The Python constant, &lt;code&gt;__debug__&lt;/code&gt; is set to &lt;code&gt;False&lt;/code&gt; during compilation, which removes assert statements from the compiled code to optimise the code for performance. Removing assert statements from the compiled code leaves the function unguarded.&lt;/p&gt;

&lt;p&gt;Another reason to avoid &lt;code&gt;assert&lt;/code&gt;s is that assertion errors are not helpful to debuggers as they provide no information other than the fact that an assertion did not hold up. Defining apt exception classes and then raising their instances is a much more solid solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For an alternative approach, go back to the basics. Here’s the same program, this time using &lt;code&gt;if/else&lt;/code&gt; and a raising a &lt;code&gt;PermissionError&lt;/code&gt; (you’ll need to define it somewhere) when the required assertion is unfulfilled.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def do_something_dangerous(user, command): if user.has_permissions(command): # [safer as it will not be removed by compiler user.execute(command) else: raise PermissionError(f'{user} is not authorized') # suitable error class
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code uses straightforward Python constructs, works the same with &lt;code&gt;__debug__&lt;/code&gt; set to &lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt; and raises clear exceptions that can be handled with much more clarity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Achieving Zen
&lt;/h2&gt;

&lt;p&gt;The key takeaway from all of these examples is to never trust your users. Input provided by the users should not be serialized-deserialized, evaluated, executed or rendered. To be safe, you must be careful of what you write and thoroughly audit the code after its been written.&lt;/p&gt;

&lt;p&gt;Do you know what’s better than scanning for vulnerabilities in code after it’s been written? Getting vulnerabilities highlighted as soon as you write code with them.&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%2Fvhev8rkpmmh2uvgk6xuj.jpg" 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%2Fvhev8rkpmmh2uvgk6xuj.jpg" width="613" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bandit
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://dzone.com/articles/top-7-static-code-analysis-tools" rel="noopener noreferrer"&gt;Static Code Analysis tools&lt;/a&gt; such as linters and vulnerability scanners can help you find a lot of issues before they get exploited in the wild. An excellent tool for finding security vulnerabilities in Python is &lt;a href="https://bandit.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;Bandit&lt;/a&gt;. Bandit goes through each file, generates an abstract syntax tree (AST) for it and then runs a whole slew of tests on this AST. Bandit can detect a whole bunch of vulnerabilities out-of-the-box and can also be extended for specific scenarios and compatibility with frameworks via plugins. As a matter of fact, Bandit is capable of detecting all of the aforementioned security shortcomings.&lt;/p&gt;

&lt;p&gt;If you’re a Python developer, I cannot recommend Bandit enough. I could write a whole article extolling its virtues. I might even do that.&lt;/p&gt;

&lt;h3&gt;
  
  
  DeepSource
&lt;/h3&gt;

&lt;p&gt;You should also consider automating this entire audit and review process using code review automation tools like DeepSource that scans your code, on every commit and for every PR, through it’s linters and security analyzers and can automatically fix a multitude of issues. &lt;a href="https://deepsource.io/" rel="noopener noreferrer"&gt;DeepSource&lt;/a&gt; also has its own custom-built analyzers for most languages that are constantly improved and kept up-to-date. And it’s &lt;a href="https://deepsource.io/docs/analyzer/python.html" rel="noopener noreferrer"&gt;incredibly easy to set up&lt;/a&gt;!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version = 1

[[analyzers]]
name = "python"
enabled = true

  [analyzers.meta]
  runtime_version = "3.x.x"
  max_line_length = 80

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Who knew it could be so simple?&lt;/p&gt;

&lt;p&gt;Experience the zen of Python, and be careful not to let black-hats disturb your peace!&lt;/p&gt;

</description>
      <category>python</category>
      <category>pythonsecurity</category>
    </item>
    <item>
      <title>Ruby best practices beginners should know</title>
      <dc:creator>Saif Sadiq</dc:creator>
      <pubDate>Mon, 18 Jan 2021 06:36:08 +0000</pubDate>
      <link>https://dev.to/deepsource/ruby-best-practices-beginners-should-know-145e</link>
      <guid>https://dev.to/deepsource/ruby-best-practices-beginners-should-know-145e</guid>
      <description>&lt;p&gt;Python’s dominance is never really questioned when it comes to the best for programming novices because it checks almost every box that defines a simple language. It’s remarkably easy to pick up and can rise to any challenge. But what about Ruby?&lt;/p&gt;

&lt;p&gt;Although it does not get enough credit for being one, Ruby is an awesome language for beginners. It provides powerful constructs (like blocks) and versatile concepts (like message passing à la Smalltalk) but retains Python’s fluid and elegant English-like syntax. In fact, in many cases, one might argue that the unique design choices that went into the Ruby syntax beat even Python in terms of readability and expressiveness. If you’re getting into programming, it’s very easy to recommend that you go with Ruby.&lt;/p&gt;

&lt;p&gt;This article aims to establish some practices that are generally accepted by the Ruby programming community. Before we dive right into how you, as a beginner, can channel Ruby’s power, let me mention two Japanese phrases that you should hold in memory: &lt;em&gt;“okonomi”&lt;/em&gt; and_“omakase”_. I promise this is relevant, and you’ll see why in a bit.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;“Okonomi”&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Ruby has always been driven by the principle to “optimize for programmer happiness” and, as a result, always offers several different ways to do the same thing, unlike Python, which has valued the philosophy of having “one and preferably only one way to do something”. As a result, many people who come to Ruby from another language find themselves baffled at the sheer number of choices the language offers for accomplishing any given task.&lt;/p&gt;

&lt;p&gt;This is what the Japanese call &lt;em&gt;“okonomi”&lt;/em&gt;, a phrase that typically applies to sushi, which translates to “I’ll choose what to order”.&lt;/p&gt;

&lt;h3&gt;
  
  
  Statements are expressions
&lt;/h3&gt;

&lt;p&gt;In Ruby, there are no statements. Every line and every command is an expression that evaluates to something. Even function definitions return something, the symbolized function name.&lt;/p&gt;

&lt;p&gt;So while you cannot hold functions in variables (something Python and JavaScript allow), you can hold their identifiers as symbols and invoke them with &lt;code&gt;send&lt;/code&gt; (more on that in a bit).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name = 'DeepSource' # returns the string 'DeepSource' itself...
b = name = 'DeepSource' # ...so this is also valid puts name # displays "DeepSource" and returns nil name.split('').select do |char| char.downcase == char # block returns true or false
end # returns ["e", "e", "p", "o", "u", "r", "c", "e"] def prime? num # ...
end # returns :prime?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How do you make the most of this?&lt;/strong&gt; This particular design decision leads to a few notable features, the most recognizable of which is that both the &lt;code&gt;return&lt;/code&gt; and &lt;code&gt;next&lt;/code&gt; keywords are, for the most part, redundant, and the recommendation is not to use them unless you want to terminate the function or block early.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def prime? num if num &amp;gt;= 2 f = (2...num).select do |i| ~~next~~ num % i == 0 end ~~return~~ f.size == 0 else ~~return~~ false end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Bye bye brackets
&lt;/h3&gt;

&lt;p&gt;In Ruby function, parentheses are, with certain caveats, optional as well. This makes Ruby ideal for defining domain-specific languages or DSLs. A domain-specific language is a language built on top of another that defines abstractions for a specific specialized purpose.&lt;/p&gt;

&lt;p&gt;For examples of DSLs, you need not look further than Rails or RSpec but for the sake of simplicity, consider Sinatra, a straightforward web server built in Ruby. This is how a simple service would look built with Sinatra.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require 'sinatra' get '/' do 'Hello, World!'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What’s not immediately apparent from this example is that &lt;code&gt;get&lt;/code&gt; here, which looks very much like a language keyword, is actually a function! The &lt;code&gt;get&lt;/code&gt; function here takes two arguments, a string path and a block that contains the code to be executed when the path matches. The return value of the block will be the HTTP response for the request matching the method and path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you make the most of this?&lt;/strong&gt; By embracing this freedom, you can define your own abstractions for your use cases! Ruby actively encourages developers to define their own little DSLs for day-to-day abstractions and write clean code by using them. The best part is that code then reads like pseudocode which is always a good thing.&lt;/p&gt;

&lt;p&gt;While parentheses are optional, the convention is to generally omit the parentheses only for zero or one arguments, while retaining them when there are more than one, for the sake of clarity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require 'date' def log message timestamp = DateTime.now.iso8601 puts "[#{timestamp}] #{message}" end log "Hello World!"
# [2020-12-30T21:18:30+05:30] Hello World!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Method names?!
&lt;/h3&gt;

&lt;p&gt;Ruby enables method names to have all sorts of punctuation such as &lt;code&gt;=&lt;/code&gt;,&lt;code&gt;?&lt;/code&gt;, &lt;code&gt;!&lt;/code&gt;. Each of these punctuation has its purpose, by convention, and indicates the particular function’s nature.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| Punctuation | Purpose | Example |
|-------------|-----------------------------------------------|-----------|
| `?` | Returns a Boolean value, `true` or `false` | .nil? |
| `!` | Modifies values in place or raises exceptions | .reverse! |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Many Ruby functions come in two variants, regular and “bang”. To understand the difference, consider this example with two variants of the &lt;code&gt;reverse&lt;/code&gt; method on strings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;str = 'DeepSource' str.reverse # "ecruoSpeeD"
str # "DeepSource" str.reverse! # "ecruoSpeeD"
str # "ecruoSpeeD"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Ruby, functions with the exclamation mark in the name modify the object they are called on. In Rails, the exclamation mark indicates that the function will raise an exception if it cannot accomplish said task instead of failing silently like its non-bang counterpart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you make the most of this?&lt;/strong&gt; You should imbibe the same convention in your code so that users of the code can easily get an idea of the function’s nature.&lt;/p&gt;

&lt;h3&gt;
  
  
  Symbols over strings
&lt;/h3&gt;

&lt;p&gt;The concept of symbols is something unique to Ruby. Symbols are just strings that are interned in memory and are not allocated new memory every time they are defined.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'text'.object_id # 200
'text'.object_id # 220 :text.object_id # 2028508
:text.object_id # 2028508
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Symbols are used in tons of places across Ruby, notably as keys for hashes and constants defining identifiers and functions.&lt;/p&gt;

&lt;p&gt;You can symbolize a string in two ways, prefixing the colon&lt;code&gt;:&lt;/code&gt; before the string (quotes are required unless the string is a valid identifier) or invoking &lt;code&gt;to_sym&lt;/code&gt; method on it.’&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:identifier # :identifier
:'not an identifier' # :"not an identifier"
'not_an_identifier'.to_sym # :"not an identifier"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How do I make the most of this?&lt;/strong&gt; The standard of defining hashes in Ruby is by using the “rocket operator” &lt;code&gt;=&amp;gt;&lt;/code&gt;. But using hashes presents a concise, cleaner, and more JavaScript-esque way to define the same.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;person_one = { 'name' =&amp;gt; 'Alice', 'age' =&amp;gt; 1 }
person_one['name'] # 'Alice' person_two = { :name =&amp;gt; 'Bob', :age =&amp;gt; 2 } # Replace strings with symbols
person_two[:name] # 'Bob' person_two = { name: 'Carol', age: 3 } # Use new style
person_two[:name] # 'Carol'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second notation is easier to read, performs better for larger data sizes, and is widely recommended now as the preferred way to define hashes. Symbols are also used for passing messages to objects using&lt;code&gt;send&lt;/code&gt; !).&lt;/p&gt;

&lt;h3&gt;
  
  
  Talk over messages
&lt;/h3&gt;

&lt;p&gt;Ruby inherits the concept of message passing from Smalltalk and goes all-in with this idea. Every method call and every variable access in Ruby is achieved by sending a message to the instance and receiving a response.&lt;/p&gt;

&lt;p&gt;Messages are sent by using the &lt;code&gt;send&lt;/code&gt; function (or &lt;code&gt;public_send&lt;/code&gt; to not bypass visibility) and passing the symbol with the name of the method you want to invoke, and any arguments that function may require. Ruby also allows you to dynamically define methods using &lt;code&gt;define_method&lt;/code&gt;(duh!) and even perform actions when a method is not defined on an object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;str = "DeepSource" str.respond_to? :reverse # true
str.send(:reverse) # "ecruoSpeeD" str.respond_to? :[] # true
str.send(:[], 4..9) # "Source" str.respond_to? :dummy # false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above examples are the same as what you could achieve by invoking the string’s &lt;code&gt;reverse&lt;/code&gt; and &lt;code&gt;split&lt;/code&gt; methods. If a class responds to a message, it will perform the action or raise an exception if it doesn’t.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I make the most of this?&lt;/strong&gt; Playing with this message functionality unlocks a whole new world of meta-programming that few other languages can match. You should try to use these features to remove boilerplate from your code and write.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Person def initialize(name, age) @name = name @age = age end [:name, :age].each do |attr| # Get getters for @name and @age with logging define_method attr do val = instance_variable_get("@#{attr}".to_sym) puts "Accessing `#{attr}` with value #{val}" val end end # Handle missing attribute puts "Person does not #{m.id2name}" end
end person = Person.new("Dhruv", 24)
person.name # "Dhruv" | prints "Accessing `name` with value Dhruv"
person.age # 24 | prints "Accessing `age` with value 24
person.sing # nil | prints "Person does not sing"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Monkey patching
&lt;/h3&gt;

&lt;p&gt;This is perhaps the most controversial but also the most powerful feature of Ruby.&lt;/p&gt;

&lt;p&gt;Monkey patching, a play on the phrases “guerrilla patching” and “monkeying about”, is the process of opening up pre-defined classes and changing their existing functionality or adding functionality to them. Ruby as a language is one of the only few that actively encourage the use of monkey patching as a legitimate way to add functionality to the language.&lt;/p&gt;

&lt;p&gt;While languages like Python and JavaScript discourage the process, Ruby embraces it and makes it dead easy to extend any class or module as simple as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class String def palindrome? self == reverse end
end 'racecar'.palindrome? # true
'arizona'.palindrome? # false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How do I make the most of this?&lt;/strong&gt; Frameworks like Rails actively use monkey patching to add features to built-in Ruby classes like &lt;code&gt;String&lt;/code&gt;and &lt;code&gt;Integer&lt;/code&gt;. If used carefully and appropriately documented, it is a powerful way of adding functionality in one location and making it available everywhere across the codebase.&lt;/p&gt;

&lt;p&gt;Care should be taken to not overdo this and only add the most general purpose code to the root classes.&lt;/p&gt;

&lt;p&gt;To drive the point home, feast your eyes on monkey patched code beauty from Rails ActiveSupport. You can install it separately from Rails and see a comprehensive list of examples in their&lt;a href="https://guides.rubyonrails.org/active_support_core_extensions.html" rel="noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;time = '2021-01-01 12:00:00'.to_time # 2020-01-01 13:00:00 +0530
day_prior = time - 1.day # 2019-12-31 13:00:00 +0530
almost_new_year = day_prior.end_of_day # 2019-12-31 23:59:59 +0530
happy_new_year = almost_new_year + 1.second # 2020-01-01 00:00:00 +0530
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.in? [1, 2, 3] # true { sym_key: 'value' }.with_indifferent_access[:sym_key.to_s] # "value"
{ 'str_key' =&amp;gt; 'value' }.with_indifferent_access['str_key'.to_sym] # "value"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Less is more
&lt;/h3&gt;

&lt;p&gt;In the pursuit of programmer happiness, Ruby is packed to the brim with syntax sugar and method aliases focused on readability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I make the most of this?&lt;/strong&gt; You should preferably use shorthand wherever Ruby’s syntax allows it because the reduced punctuation and added conciseness makes the code easier to read and process mentally.&lt;/p&gt;

&lt;p&gt;Want to make an arrays of strings, symbols or numbers? Use &lt;code&gt;%&lt;/code&gt; notation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;%w[one two three] # ["one", "two", "three"]
%i[one two three] # [:one, :two, :three]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are uppercase versions of these shorthands that also allow interpolation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pfx = 'item'
%W[#{pfx}_one #{pfx}_two #{pfx}_three] # ["item_one", "item_two", "item_three"]
%I[#{pfx}_one #{pfx}_two #{pfx}_three] # [:item_one, :item_two, :item_three]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another interesting shorthand notation is when you’re trying to map or select over an array, and all you want to do is invoke a single method on all of the objects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;strings = %w[one two three]
strings.map &amp;amp;:upcase # ~ strings.map { |str| str.upcase! }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Many of the operations we take for granted in a programming language, like mathematical operations, are all syntax sugar notations! Since Ruby is built on message passing, any valid string is a valid method name such as &lt;code&gt;+&lt;/code&gt; or &lt;code&gt;[]&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.+(2) # ~ 1 + 2 words = %w[zero one two three four]
words.[](2) # ~ words[2]
words.&amp;lt;&amp;lt;('five') # ~ words &amp;lt;&amp;lt; 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;em&gt;“Omakase”&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Remember the other word I asked you to remember when we started? I promised it was relevant. &lt;em&gt;“Omakase”&lt;/em&gt; is an opposite version of an_“okonomi”_ meal, this time consisting of sushi selected for you by the chef. While Ruby’s offer of several ways to accomplish something boosts creativity and expression, it comes with its own set of drawbacks, especially when it comes to consistency and &lt;a href="https://deepsource.io/blog/code-review-best-practices/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=contentdistribution&amp;amp;utm_term=rubybestpractices" rel="noopener noreferrer"&gt;code review&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def is_prime(num) if num &amp;gt;= 2 f = (2...num).select do |i| next num % i == 0 end return f.size == 0 else return false end
end is_prime(0) # false
is_prime(1) # false
is_prime(2) # true
is_prime(3) # true
is_prime(4) # false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Integer def prime? return false if self &amp;lt; 2 (2...self).none? { |i| self % i == 0 } end
end 0.prime? # false
1.prime? # false
2.prime? # true
3.prime? # true
4.prime? # false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Based on what we’ve leaned, we can make the following changes to the code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;monkey patch method definition into the &lt;code&gt;Integer&lt;/code&gt; class&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;?&lt;/code&gt; in method names that have a Boolean return type&lt;/li&gt;
&lt;li&gt;remove redundant parentheses &lt;code&gt;( )&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;exit early instead of indenting the entire code inside an &lt;code&gt;if&lt;/code&gt; block&lt;/li&gt;
&lt;li&gt;remove redundant &lt;code&gt;return&lt;/code&gt; and &lt;code&gt;next&lt;/code&gt; keywords&lt;/li&gt;
&lt;li&gt;inline blocks with a single expression using braces &lt;code&gt;{ }&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;use from Ruby’s huge assortment built-in functions, such as&lt;code&gt;Array::none?&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using a comprehensive style guide and linter is key when getting started with programming in any new language. Not only does it improve the quality of your code, but it also provides you an excellent way to learn by pointing out improvements in real-time as you code.&lt;/p&gt;

&lt;p&gt;A linter will reduce the number of ways you have for writing a program, but what you lose in the creativity of expression is more than made up for inconsistency and code clarity. I would gladly make that trade-off even as a professional, much more so if I were a novice.&lt;/p&gt;

&lt;p&gt;Let me recommend two tools that you should use as a beginner.&lt;/p&gt;

&lt;h3&gt;
  
  
  RuboCop
&lt;/h3&gt;

&lt;p&gt;When it comes to a linter for Ruby, nothing comes even close to&lt;a href="https://rubocop.org" rel="noopener noreferrer"&gt;RuboCop&lt;/a&gt;. It’s a linter, formatted, and style guide rolled into one, and while it is configurable, the configuration that shipped with out-of-the-box is more than enough to put you on the right track for code quality. RuboCop also helps you &lt;a href="https://deepsource.io/blog/ruby-security-pitfalls/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=contentdistribution&amp;amp;utm_term=rubybestpractices" rel="noopener noreferrer"&gt;scan for security vulnerabilities&lt;/a&gt;, giving you yet another reason to set it up.&lt;/p&gt;

&lt;p&gt;Install and try it out today. Your future self will thank you, and possibly me as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  DeepSource
&lt;/h3&gt;

&lt;p&gt;When it comes to working in a team, reviewing other people’s code becomes important. DeepSource is an automated code review tool that manages the end-to-end code scanning process and automatically makes pull requests with fixes whenever new commits are pushed, or new pull requests are opened against the main branch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://deepsource.io/blog/ruby-general-availability-release/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=contentdistribution&amp;amp;utm_term=rubybestpractices" rel="noopener noreferrer"&gt;Setting up DeepSource for Ruby&lt;/a&gt; is extremely easy. As soon as you have it set up, it will scan your entire codebase, find scope for improvements, fix them, and open PRs for those changes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That’s all folks!&lt;/em&gt; Have fun learning Ruby, it’s a fantastic language.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rubybestpractices</category>
      <category>rubytutorial</category>
    </item>
    <item>
      <title>Beginner's guide to JavaScript static code analysis</title>
      <dc:creator>Saif Sadiq</dc:creator>
      <pubDate>Mon, 11 Jan 2021 08:35:21 +0000</pubDate>
      <link>https://dev.to/deepsource/beginner-s-guide-to-javascript-static-code-analysis-55d6</link>
      <guid>https://dev.to/deepsource/beginner-s-guide-to-javascript-static-code-analysis-55d6</guid>
      <description>&lt;p&gt;Do you suffer from poorly written code? Is your codebase riddled with inconsistencies? Do you experience anxiety every time your code is being reviewed? If you answered ‘yes’ to any of these questions, static code analysis could help.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://deepsource.io/blog/introduction-static-code-analysis/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=contentdistribution&amp;amp;utm_term=jsstaticanalysis" rel="noopener noreferrer"&gt;Static code analysis&lt;/a&gt; is the process of analyzing code &lt;em&gt;before&lt;/em&gt; it is executed. It provides numerous advantages to developers, and integrating static code analyzers can supercharge your developer workflow.&lt;/p&gt;

&lt;p&gt;Let’s take a deep dive to understand what static code analysis is, why you should be using it when to start, and how you can quickly set it up in your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Static Code Analysis?
&lt;/h2&gt;

&lt;p&gt;Of all the questions we just raised, this is probably the easiest to answer. As the name says, Static code analysis is the analysis of code in a static or non-executing state. It is the automated equivalent to another developer reading and reviewing your code, except with the added efficiency, speed, and consistency afforded by a computer that no human could match.&lt;/p&gt;

&lt;h3&gt;
  
  
  How is it different from testing?
&lt;/h3&gt;

&lt;p&gt;You might be thinking, “If I write detailed tests of all my units and functional tests at a system level, and they all pass, my code is bug-free, right?” Yes, it is. Congratulations. But bug-free code is not the same as good code; there’s a lot more that goes into that. That is the domain where static analysis shines.&lt;/p&gt;

&lt;p&gt;All types of tests, be it unit tests, functional tests, integration tests, visual tests, or regression tests, run the code and then compare the outcome against known expected-state outputs to see if everything works OK. Testing makes sure your code functions as expected. It treats your code as a black box, giving it input and verifying the output.&lt;/p&gt;

&lt;p&gt;On the other hand, static code analysis analyses its aspects such as readability, consistency, error handling, type checking, and alignment with best practices. &lt;a href="https://deepsource.io/glossary/static-analysis/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=contentdistribution&amp;amp;utm_term=jsstaticanalysis" rel="noopener noreferrer"&gt;Static analysis&lt;/a&gt; is not primarily concerned with whether your code provides the expected output but rather with how the code itself is written. It’s an analysis of the quality of source code, not its functionality.&lt;/p&gt;

&lt;p&gt;To summarise, testing checks if your code works or not, whereas static analysis checks if it is written well or not. Testing and static analysis are complementary to each other, and you should ideally be employing a healthy mix of both in your projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Static Code Analysis?
&lt;/h2&gt;

&lt;p&gt;Any tool that reads the source code, parses it, and suggests improvements is a static code analyzer. There are many &lt;a href="https://dzone.com/articles/top-7-static-code-analysis-tools" rel="noopener noreferrer"&gt;tools&lt;/a&gt; that fall under the umbrella term of static code analyzers, from linters and formatters to vulnerability scanners and PR reviewers. Let’s go over the main reasons why you should use these in your workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  In-depth code scanning
&lt;/h3&gt;

&lt;p&gt;Ask any developer, and they’ll corroborate that code reviews are essential. A second pair of eyes can discover issues in your code you probably never could. They might quite possibly suggest better ways to accomplish the task too. Sometimes reading other people’s code can teach the reviewer about some obscure useful functionality that’s already built into the project. Both the reviewer or the reviewee (which might not be a real word but one I will use nonetheless) learn something in the process.&lt;/p&gt;

&lt;p&gt;But what’s better than one person reviewing your code? How about every open-source developer reviewing it! Static analyzers are powered by a vast library of open-source rules, which means that everyone who has contributed to the tool has indirectly reviewed your code. This makes it very hard to subtle bugs that a couple of human reviewers could miss, to slip by.&lt;/p&gt;

&lt;p&gt;People make mistakes. Only 15% of codebases that install JSHint, a popular code-review tool for JavaScript, pass without issues. That just goes to show how vital it is to have some computer eyes review your code as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consider this program for letting the user pick their favourite fruit. If you don’t choose, ‘Mango’ is the default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let fruits = ['Apple', 'Banana', 'Cherry', 'Mango']
function getFruit(index) { index = index || 3 // Everybody likes mangoes
    return fruits[index]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code works. For all inputs other than &lt;code&gt;0&lt;/code&gt; that is. If you aren’t very thorough, your tests will also pass without a single hiccup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;getFruit() // Mango
getFruit(2) // Cherry
getFruit(0) // Mango (expected Apple!)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Turns out, you can’t choose an apple in this program because &lt;code&gt;0&lt;/code&gt;, like &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; is a falsy value. You should have used the null-coalescing operator (&lt;code&gt;??&lt;/code&gt;) instead, and a linter would have told you that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let fruits = ['Apple', 'Banana', 'Cherry', 'Mango']
function getFruit(index) { index = index ?? 3 // Everybody likes mangoes
    return fruits[index]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Guard rails and training wheels
&lt;/h3&gt;

&lt;p&gt;Every developer writes code differently in their own personal style. But when many developers are working together, it is important that they write code in a consistent manner. That’s where a style guide comes in. Setting one up is the first step to writing consistent code, and its enforcement extremely important when working with other developers.&lt;/p&gt;

&lt;p&gt;Enforcing a style guide is not a manual feat. No developer can be expected to remember hundreds of rules and check every line against each of them. Why not make the computer do it?&lt;/p&gt;

&lt;p&gt;Every language that I’ve ever worked in has a linter written for it. &lt;a href="https://eslint.org" rel="noopener noreferrer"&gt;JavaScript has ESLint&lt;/a&gt;; &lt;a href="https://black.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;Python has Black&lt;/a&gt;, and &lt;a href="https://github.com/rubocop-hq/rubocop" rel="noopener noreferrer"&gt;Ruby has RuboCop&lt;/a&gt;. These linters do the simple job of making sure your code follows the prescribed set of style rules. A few linters like RuboCop also enforce good practices such as atomic functions and better variable names. Such hints are very often helpful in detecting and fixing bugs before they cause issues in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consider the following JavaScript snippet where you print a fruit name from a list. The list remains unchanged throughout the program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var fruits = ['Apple', 'Banana', 'Cherry', 'Mango']
console.log(fruits[0])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ESLint, if so configured, can make sure you use constants wherever possible to avoid side-effects in your code. It’s a good practice but easy to miss if you don’t have a linter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fruits = ['Apple', 'Banana', 'Cherry', 'Mango']
console.log(fruits[0])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enforcing the use of &lt;code&gt;const&lt;/code&gt; and &lt;code&gt;let&lt;/code&gt;, which are block-scoped, over &lt;code&gt;var&lt;/code&gt; leads to programs that are easier to debug and is generally considered a good practice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Discover issues instantly…
&lt;/h3&gt;

&lt;p&gt;Another thing developers love is testing their code, making sure it holds up for various inputs. Practices like test-driven development emphasize the importance of testing the code that you write. But writing tests takes time and effort. It is hard to gauge every possible input and make sure your code holds up to that. Eventually, tests become too many and take hours to complete on larger codebases.&lt;/p&gt;

&lt;p&gt;Static code analyzers do not suffer from this issue. You don’t need to write the tests; you can import entire libraries of presets. Additionally, static analyzers run incredibly fast as there is no code execution involved! In fact, many linters integrate with the editor and highlight issues with the code in real-time as you type.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&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%2Fhwq716b26fu3e1gsetbw.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%2Fhwq716b26fu3e1gsetbw.png" alt="https://i.redd.it/uwc7cddddcp51.png" width="640" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sometimes, real-time is just too fast.&lt;/p&gt;

&lt;h3&gt;
  
  
  …fix them just as fast
&lt;/h3&gt;

&lt;p&gt;Most static analyzers, especially linters and formatters, will not just point out issues but can also fix most of them for you. Linters like &lt;a href="https://black.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;Black for Python&lt;/a&gt; and &lt;a href="https://eslint.org" rel="noopener noreferrer"&gt;ESLint for JavaScript&lt;/a&gt; integrate with IDEs and can then automatically fix the edited files as soon as you save them.&lt;/p&gt;

&lt;p&gt;This is extremely convenient because now, your code quality improves without you having to even consciously think about it. As developers, we’re spoilt for convenience, aren’t we?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ESLint has the &lt;code&gt;--fix&lt;/code&gt; flag that fixes common issues like unnecessary semicolons, trailing spaces, and dangling commas.&lt;/p&gt;

&lt;p&gt;Consider the same code snippet from the past few examples. (Here the · represents a space.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var fruits = [ 'Apple', 'Banana', 'Cherry',·· 'Mango'
];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run ESLint with the &lt;code&gt;--fix&lt;/code&gt; flag and moments later you have this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fruits = [ 'Apple', 'Banana', 'Cherry', 'Mango',
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Much better!&lt;/p&gt;

&lt;h3&gt;
  
  
  Bill of materials
&lt;/h3&gt;

&lt;p&gt;A bill of materials is generally used in supply chain management as the cost of just the raw materials that go into any product. A similar bill of materials is needed for software as well.&lt;/p&gt;

&lt;p&gt;When you build an app, you inevitably use frameworks and tools that were built by other developers. In turn, those frameworks use frameworks built by other developers. And before you know it, setting up a simple Vue.js app can put thousands of packages in your &lt;code&gt;node_modules/&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;This is the scary reality we live in. Packages built on top of packages. Each giant is standing on the shoulders of another. Your app is only as strong as its weakest dependency. Vulnerability scanners are another set of static analyzers that check every dependency in your dependency tree against an extensive database of vulnerabilities and exploits. All packages that have a known vulnerability are reported and can be updated with a single command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GitHub provides dependency scanning with Dependabot. &lt;code&gt;npm&lt;/code&gt; also provides a vulnerability scan using the &lt;code&gt;npm audit&lt;/code&gt; command. Both Dependabot and &lt;code&gt;npm audit&lt;/code&gt; offers the ability to automatically update vulnerable packages to their patched versions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automate the boring stuff
&lt;/h3&gt;

&lt;p&gt;Manual code reviews waste a lot of time. The person doing the review has to take time out of their own work to do the review, go through the code, and point out all the different places where it could be improved, both logically but also in the tiny details such as incorrect formatting or deviation from conventions and style guides. Then the reviewer has to make all the suggested changes and repeat the process.&lt;/p&gt;

&lt;p&gt;Adding some linters, formatters, and spell checkers make the entire process much more streamlined. How so, you ask? First, a pre-commit hook will ensure that code is properly linted and formatted before getting checked-in to VCS. Second, project-level automation in the form of build pipelines or GitHub workflows will test the code quality on every commit and highlight issues on the PR itself. Third, the reviewer will be freed up to focus on the big picture because all the smaller things have already been handled before the PR makes it to a manual review.&lt;/p&gt;

&lt;p&gt;No amount of code review by software can entire replace manual review. But a static scan before a manual review can easily augment both the reviewer’s experience by reducing their effort and getting the developer’s code reviewed by iterating on the smaller issues faster and more thoroughly than many rounds of manual reviews.&lt;/p&gt;

&lt;h2&gt;
  
  
  The When
&lt;/h2&gt;

&lt;p&gt;Now. Yes, that’s correct. I did say right now. Any later than right now is too late. You would have reached step two of ‘The How’ if I didn’t have to convince you as much.&lt;/p&gt;

&lt;h2&gt;
  
  
  The How
&lt;/h2&gt;

&lt;p&gt;Setting up is easy. Since we’ve repeatedly been talking about ESLint here, let’s just set it up in a sample project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Make a new project
&lt;/h3&gt;

&lt;p&gt;Make a new directory for your project. Enter the directory and initialise a Node.js package in the directory. The &lt;code&gt;npm init&lt;/code&gt; wizard asks you a series of questions. Once you’re done, you have a new Node.js package to work in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir wuphf.com
$ cd wuphf.com
$ npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install ESLint
&lt;/h3&gt;

&lt;p&gt;Install ESLint. It’s too simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install eslint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure ESLint
&lt;/h3&gt;

&lt;p&gt;Run the following command to bring up the ESLint wizard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ./node_modules/.bin/eslint --init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This wizard asks a lot of questions about the how you will be using ESLint in the project. Make sure to choose the Airbnb ruleset. When the setup is complete, will will have a file &lt;code&gt;.eslintrc.js&lt;/code&gt; in the directory.&lt;/p&gt;

&lt;p&gt;This file defines that the project will be running on Node.js and it will be building on top of the rules defined in the Airbnb style guide. Since we’re writing a console application, I can customise the rules and turn off the one that warns against it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = { env: { es2021: true, node: true, }, extends: ['airbnb-base',], parserOptions: { ecmaVersion: 12, }, overrides: [{ files: ['*.js'], rules: { 'no-console': 'off', }, }, ],
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit this file into version control.&lt;/p&gt;

&lt;p&gt;There you have it! All JS file in the project will now be continuously scanned by ESLint. I also recommend install &lt;a href="https://typicode.github.io/husky/#/" rel="noopener noreferrer"&gt;Husky&lt;/a&gt; to run a lint job before every commit so that you never check in poor code into your VCS ever.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automate everything with DeepSource
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://deepsource.io/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=contentdistribution&amp;amp;utm_term=jsstaticanalysis" rel="noopener noreferrer"&gt;DeepSource&lt;/a&gt; is a static code analyzer that can find issues in the codebase and automatically submit PRs to fix them. It can even evaluate incoming code in PRs and fix them too. It’s wonderful how well it integrates with GitHub, GitLab, and Bitbucket.&lt;/p&gt;

&lt;p&gt;You can set up DeepSource in a project by dropping a single TOML file named &lt;code&gt;.deepsource.toml&lt;/code&gt; in the root of the repo and it will pick the project up and start scanning. Most major languages are supported.&lt;/p&gt;

&lt;h3&gt;
  
  
  The End
&lt;/h3&gt;

&lt;p&gt;That is all. It’s really simple to statically analyze your code, and the benefits are so many that there’s no reason not to be doing it.&lt;/p&gt;

&lt;p&gt;Have fun writing cleaner, safer, more readable, and more maintainable (simply put, better) code, and we’ll see you in the next one.&lt;/p&gt;

</description>
      <category>staticcodeanalysis</category>
      <category>javascript</category>
      <category>javascriptguide</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Using state machine to write bug-free code</title>
      <dc:creator>Saif Sadiq</dc:creator>
      <pubDate>Tue, 29 Dec 2020 11:32:36 +0000</pubDate>
      <link>https://dev.to/deepsource/using-state-machine-to-write-bug-free-code-596l</link>
      <guid>https://dev.to/deepsource/using-state-machine-to-write-bug-free-code-596l</guid>
      <description>&lt;p&gt;The first time you heard of a state machine, what did you think it was? I thought it was a debugger. A debugger I could use to find those annoying bugs in my code. A state machine is not a debugger. However, when you master how to use a state machine, the code you write would be on the bug-free side.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a State Machine?
&lt;/h2&gt;

&lt;p&gt;A state machine is an abstract concept that defines and plans the stages and transitions of an application. The application only transitions upon the occurrence of an event. A state machine indicates the initial state of an app, for example, and what would be the next stage – transition – if a user uses the app.&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%2Fdeepsource.io%2Fimages%2Fblog%2Fusing-state-machine-to-write-bug-free-code%2Fwhat-is-state-machine.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%2Fdeepsource.io%2Fimages%2Fblog%2Fusing-state-machine-to-write-bug-free-code%2Fwhat-is-state-machine.png" title="What is a State Machine?" alt="What is a State Machine?" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, in a functioning Automated Teller Machine (ATM), where you can insert your card, it displays a message like welcome on its screen. That is how the programmer who programmed the ATM designed the initial state of the machine. Once you insert your card, the ATM changes its display and asks for your password. By inserting your card, the ATM transitions to another state. If you enter the right password, the ATM displays its services – withdraw, account balance, transfer, and so on. Each ATM services is a state the ATM could transition.&lt;/p&gt;

&lt;p&gt;By clicking on a service rendered by the ATM, it transitions to another state - where you can either withdraw or transfer funds or check your account balance. It depends on what you click.&lt;/p&gt;

&lt;p&gt;If you enter the wrong password, the ATM changes to another state that says “sorry, you enter the wrong password” or something like that.&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%2Fdeepsource.io%2Fimages%2Fblog%2Fusing-state-machine-to-write-bug-free-code%2Fatm-machine-example.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%2Fdeepsource.io%2Fimages%2Fblog%2Fusing-state-machine-to-write-bug-free-code%2Fatm-machine-example.png" title="ATM machine example" alt="ATM machine example" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The programmer has planned every state and transition of the ATM. That means if user A, for example, clicks a button on the ATM, the machine changes to a particular state.&lt;/p&gt;

&lt;p&gt;Of recent, I wanted to access my account on a platform through Google Chrome. I entered my username and password. The website sent a One Time Code (OTP) to my phone number to ensure I was the person trying to login. When I clicked Sign in, the app moved from the sign-in page and threw a bug – it displayed a blank page. There was no place I could enter the code.&lt;/p&gt;

&lt;p&gt;Having a planned state machine would have solved the bug. In an instance where the state machine had been well planned, once you click sign-in and you receive the code on your phone, the next page should either be a page having an empty box where you can enter the code or raise an error and direct you back to the sign-in page.&lt;/p&gt;

&lt;p&gt;That is how a state machine helps you write bug-free code. The code you write would have envisaged each state of the code, what makes it transition, and to what state.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Design State Machine to Write a Bug-free Code
&lt;/h2&gt;

&lt;p&gt;The reason why you have bugs in software is as a result of an input sent to the wrong state. Remember my account login details sent to a blank page? That was because of an inefficient state machine.&lt;/p&gt;

&lt;p&gt;To avoid such bugs, here are steps on how to design a well-planned state machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Identify initial state
&lt;/h3&gt;

&lt;p&gt;Before you write a code, identify the first state of your application when it becomes a finished product. As an example, initial states like sign-in and or register page. The initial state in the diagram below is the idle state. The idle state could be the sign-in or register state or both. You should first identify the initial stage when the code you write becomes a finished product.&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%2Fdeepsource.io%2Fimages%2Fblog%2Fusing-state-machine-to-write-bug-free-code%2Fidentify-initial-state.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%2Fdeepsource.io%2Fimages%2Fblog%2Fusing-state-machine-to-write-bug-free-code%2Fidentify-initial-state.png" title="Identify initial state" alt="Identify initial state" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Identify events
&lt;/h3&gt;

&lt;p&gt;Events are what cause an application to move from a state to another – transition. Events could be anything resulting in changes – input, clicks, camera caption, and more. For example, you ordered goods on an e-commerce website; the website takes you to a page where you can request shipping of the goods. On that same page, there is also an option to cancel your order. Ordering the goods or canceling the order is an event.&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%2Fdeepsource.io%2Fimages%2Fblog%2Fusing-state-machine-to-write-bug-free-code%2Fidentify-events.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%2Fdeepsource.io%2Fimages%2Fblog%2Fusing-state-machine-to-write-bug-free-code%2Fidentify-events.png" title="Identify events" alt="Identify events" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Identify each event that could make your application transition; this makes your code bug-free. You would have programmed your code to allow specific actions: whether to take a user to the next page or stage - or throw an error message and take a user back to the previous state.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Determine transition
&lt;/h3&gt;

&lt;p&gt;Map out each state your application would be when an input or an action occurs. When a user uses your app, what are the stages the app could move? For instance, you programmed a web application that allows users to borrow books. The first state of the application displays a search box where a user can search for the names of books. If a user enters the name of a book, the app either takes the user to the page where the book is or displays: sorry, the book is not found or on loan. These are transitions - an application moving from one predetermined state to another because of an event.&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%2Fdeepsource.io%2Fimages%2Fblog%2Fusing-state-machine-to-write-bug-free-code%2Fdetermine-transition.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%2Fdeepsource.io%2Fimages%2Fblog%2Fusing-state-machine-to-write-bug-free-code%2Fdetermine-transition.png" title="Determine transition" alt="Determine transition" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, there is an issue a state machine should solve in the above example. What happens if a user enters the name of the book he is looking for and press the search button; while the app is still processing the search, the user inputted a name of a different book and pressed the search button again?&lt;/p&gt;

&lt;p&gt;In this case, a code having a well-planned state machine would make the second search ineffective till the first search completes. A state machine you planned based on each state helps you identify bugs and also puts you in control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why State Machine Needs to Be Designed From a State Perspective and Not Transition
&lt;/h2&gt;

&lt;p&gt;Design a state machine based on the states an application would fall in; such an application does not run into bugs. The design would consider each state the application would be, and each event that should occur before there is a transition. By this, a programmer writes a lesser code and is in control of its application. An application will only carry out functions it is programmed to do and reject everything else.&lt;/p&gt;

&lt;p&gt;More so, a code would achieve the business logic behind it. The code, in a strict sense, achieves its aim. Take a book reader app as an example. The book reader allows users to store and read books in it. That is the business logic behind the creation of the app. To make people keep and read books on it.&lt;/p&gt;

&lt;p&gt;You write long codes in a state machine designed from a transition perspective. Your code would use a lot of conditions trying to accommodate all possible actions a user could take. Along the line, you may lose control and focus on why you’re writing a code. Your application risks running into many bugs. Transitions are, most times, unknown at the beginning. The best is to determine the states of your app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;A state machine defines and plans the stages of an application. It is planning a code on how it should work. A state machine ensures a code is bug-free. It also makes sure the business logic behind writing it is achieved.&lt;/p&gt;

</description>
      <category>statemachine</category>
      <category>bugfreecode</category>
      <category>coding</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
