<?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: Factorial</title>
    <description>The latest articles on DEV Community by Factorial (@factorial).</description>
    <link>https://dev.to/factorial</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%2F1288%2Fb8fabc64-9c16-4ac7-87df-63f3198102e1.png</url>
      <title>DEV Community: Factorial</title>
      <link>https://dev.to/factorial</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/factorial"/>
    <language>en</language>
    <item>
      <title>Don't create leftovers (DCL)</title>
      <dc:creator>Ferran Basora</dc:creator>
      <pubDate>Thu, 26 Nov 2020 19:09:57 +0000</pubDate>
      <link>https://dev.to/factorial/don-t-create-leftovers-dcl-412g</link>
      <guid>https://dev.to/factorial/don-t-create-leftovers-dcl-412g</guid>
      <description>&lt;p&gt;Everybody is familiar with the &lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself" rel="noopener noreferrer"&gt;DRY&lt;/a&gt; principle in software engineering coined by Andy Hunt and Dave Thomas. It states &lt;em&gt;do not repeat yourself&lt;/em&gt; in code to achieve less ambiguous code, avoid redundancy, and many other benefits in the long term.&lt;/p&gt;

&lt;p&gt;In this post, I want to explain another pattern that I see over and over in all kind of projects and it brings problems and impacts the maintainability of your software project. It doesn't affect the source code itself but the organization of the files that compose it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a leftover?
&lt;/h2&gt;

&lt;p&gt;In the lifespan of a software project, code gets created and destroyed to meet users' expectations. During this period, it is easy to generate files, components, and other kinds of stuff that are not used any more. Those undesired pieces of software, make it harder to maintain, impact on your internal metrics, slow down your Continuous Integration check and other kinds of side effects.&lt;/p&gt;

&lt;p&gt;Those leftovers from the past, don't bring any value to the project and it can get to the point where nobody is brave enough to do a right cleanup to have a healthy codebase. This goes directly to the technical debt bucket.&lt;/p&gt;

&lt;p&gt;Those items should have been removed when the last reference to them disappeared but a developer forgot to remove them. Those leftovers can be a unused image, a unused copy, a unused test on your test suite, etc.&lt;/p&gt;

&lt;p&gt;You can find many similarities and parallelisms with the responsibilities of a memory garbage collector. It keeps tracks the dependencies between parts, with a &lt;a href="https://en.wikipedia.org/wiki/Reference_counting" rel="noopener noreferrer"&gt;reference counting&lt;/a&gt; to be able to destroy all unused references. The problem here is that we don't track this kind of information between the dependencies in our code base.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do we create leftovers?
&lt;/h2&gt;

&lt;p&gt;This bad design pattern can have many shapes. This is another example where &lt;em&gt;Don't create leftovers&lt;/em&gt; impacts many projects today. How many of you have a translation system where translations live in one place and the place where they are used is in another one?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;src/translations/en.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hello_world"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello World!"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;src/components/hello_world.jsx&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;HelloWorld&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="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i18n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello_world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;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;The problem with this translation approach is that if the &lt;code&gt;HelloWorld&lt;/code&gt; component disappears in the future, the copy in &lt;code&gt;en.json&lt;/code&gt; will be forgotten unless a developer remembers to clean it up. At some point in the future, your main translation file starts to have hundreds of unused keys that make you lose money with each new language you want to support.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fferranbasora.com%2F_next%2Fimage%3Furl%3D%252Fposts%252Fdont-create-leftovers%252Fdependencies.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fferranbasora.com%2F_next%2Fimage%3Furl%3D%252Fposts%252Fdont-create-leftovers%252Fdependencies.png%26w%3D3840%26q%3D75" alt="Example of translation dependencies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some &lt;a href="https://formatjs.io/docs/getting-started/message-extraction" rel="noopener noreferrer"&gt;translation systems&lt;/a&gt; are aware of this and follow a much better approach. They have an &lt;em&gt;extraction&lt;/em&gt;&lt;br&gt;
step to retrieve all translations from the codebase. With this, the list of used copies (dependencies) is always up to date.&lt;/p&gt;
&lt;h2&gt;
  
  
  Other examples
&lt;/h2&gt;

&lt;p&gt;How many times have you seen a web platform tutorial where the &lt;code&gt;assets&lt;/code&gt; folder and the place where they are used is far away?&lt;/p&gt;

&lt;p&gt;Take this easy file structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/assets/images/
  - post1-cover.jpg
  - post1-thumbnail.jpg
/posts/post1/
  - helper.js
  - index.jsx
/specs/
  - helper.spec.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This structure can be familiar to you, but it suffers from DCL. If for some reason the &lt;code&gt;post1&lt;/code&gt; is no longer needed and it disappears, it is really probable that the &lt;code&gt;helper.spec.js&lt;/code&gt; file will be removed after a failing test but those &lt;code&gt;assets&lt;/code&gt; related to &lt;code&gt;post1&lt;/code&gt; will be forgotten forever.&lt;/p&gt;

&lt;p&gt;Check this other example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;components/
  List/
    index.jsx (has a dependency with ListItem)
  ListItem/
    index.jsx
stories/
  List.story.jsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although this file organization seems inoffensive, it suffers from DCL too. If the &lt;code&gt;List&lt;/code&gt; component disappears, maybe the &lt;code&gt;List.story.jsx&lt;/code&gt; will fail as a side-effect but nobody will alert you that &lt;code&gt;ListItem&lt;/code&gt; needs to be removed too.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to detect it?
&lt;/h2&gt;

&lt;p&gt;This principle shows up like references to parent components or external resources, but sometimes it is harder to detect it.&lt;/p&gt;

&lt;p&gt;The rule of thumbs in all cases is to answer yourself the question:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If I remove this component or piece of code from my code base, will I create leftovers?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With this question, you imagine yourself in the future removing this shiny new code and seeing all the unused pieces in your source code. Answering this question at this point helps you to know all the dependencies this code has.&lt;/p&gt;

&lt;h2&gt;
  
  
  Better approach
&lt;/h2&gt;

&lt;p&gt;To fix this organization problem, the best approach is to encapsulate better all the dependencies. In the case of file structures try to avoid having dependencies to parent components if a dependency is only used once and move them as child components. All those dependencies can start to use relative paths.&lt;/p&gt;

&lt;p&gt;Following the previous example, this would be a much better organization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/components/
  List/
    ListItem/
      index.jsx
    index.jsx
    index.story.jsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This new approach has much better encapsulation and a clear set of dependencies. One direct benefit of this is that it lets you move this component to others around without breaking it.&lt;/p&gt;

&lt;p&gt;In some cases, like the translations example, you will need some extra step in your toolchain to resolve those dependencies of your views. In the case of the assets one, you will need your builder (Ex. Webpack) to have support to resolve them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We just reviewed a few examples of the &lt;em&gt;don't create leftovers&lt;/em&gt; principle.&lt;br&gt;
Understanding the consequences in terms of maintainability, you will be able to create and organize your components in a better way that will let you maintain your code base in a healthier way in the long term.&lt;/p&gt;

&lt;p&gt;You don't need to take this principle as written in stone. There are always exceptions or edge cases, as in DRY principle, we don't have to fall on &lt;em&gt;the wrong abstraction&lt;/em&gt; as Sandi Metz mentioned. You have to use it and keep it&lt;br&gt;
in mind when you structure your components, views, assets or&lt;br&gt;
whatever piece in your project.&lt;/p&gt;

&lt;p&gt;I hope this post helps you to spot this pattern sooner rather than later to keep the maintainability of your project under control.&lt;/p&gt;

&lt;p&gt;Happy hacking!&lt;/p&gt;

</description>
      <category>codequality</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>A trick with the Ruby documentation</title>
      <dc:creator>Fran C.</dc:creator>
      <pubDate>Tue, 28 Jul 2020 06:28:47 +0000</pubDate>
      <link>https://dev.to/factorial/a-trick-with-the-ruby-documentation-58m7</link>
      <guid>https://dev.to/factorial/a-trick-with-the-ruby-documentation-58m7</guid>
      <description>&lt;p&gt;I've never been able to remember the arguments for &lt;code&gt;Array#reduce&lt;/code&gt;. Every time I think I've managed to do it I just get it wrong.&lt;/p&gt;

&lt;p&gt;Luckily for me, Ruby has very good documentation on its standard library and, what's even better, it ships with a CLI to explore it so I don't even need to Google it 😬&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ri "Array#reduce"
&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;= Array#reduce

(from ruby core)
=== Implementation from Enumerable
------------------------------------------------------------------------
  enum.reduce(initial, sym) -&amp;gt; obj
  enum.reduce(sym)          -&amp;gt; obj
  enum.reduce(initial) { |memo, obj| block }  -&amp;gt; obj
  enum.reduce          { |memo, obj| block }  -&amp;gt; obj

------------------------------------------------------------------------

Combines all elements of enum by applying a binary operation,
specified by a block or a symbol that names a method or operator.

The inject and reduce methods are aliases. There
is no performance benefit to either.

If you specify a block, then for each element in enum the block
is passed an accumulator value (memo) and the element. If you
specify a symbol instead, then each element in the collection will be
passed to the named method of memo. In either case, the result
becomes the new value for memo. At the end of the iteration, the
final value of memo is the return value for the method.

If you do not explicitly specify an initial value for
memo, then the first element of collection is used as the
initial value of memo.

  # Sum some numbers
  (5..10).reduce(:+)                             #=&amp;gt; 45
  # Same using a block and inject
  (5..10).inject { |sum, n| sum + n }            #=&amp;gt; 45
  # Multiply some numbers
  (5..10).reduce(1, :*)                          #=&amp;gt; 151200
  # Same using a block
  (5..10).inject(1) { |product, n| product * n } #=&amp;gt; 151200
  # find the longest word
  longest = %w{ cat sheep bear }.inject do |memo, word|
     memo.length &amp;gt; word.length ? memo : word
  end
  longest                                        #=&amp;gt; "sheep"

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

&lt;/div&gt;



&lt;p&gt;It has a very good interactive mode as well (&lt;code&gt;ri -i&lt;/code&gt;) In which you can search whatever you want :)&lt;/p&gt;

&lt;p&gt;Oh, and if you use Vim you can access it by using &lt;code&gt;K&lt;/code&gt; over any word. Check this out:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3y3gxynkolbmrxwwonjd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3y3gxynkolbmrxwwonjd.gif" alt="K opens vim docs in vim"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
    <item>
      <title>Why most developers fail their first tech interviews</title>
      <dc:creator>Gerard</dc:creator>
      <pubDate>Mon, 11 May 2020 07:32:50 +0000</pubDate>
      <link>https://dev.to/factorial/why-most-developers-fail-their-first-tech-interviews-28jn</link>
      <guid>https://dev.to/factorial/why-most-developers-fail-their-first-tech-interviews-28jn</guid>
      <description>&lt;p&gt;In the last 4 years interviewing candidates for development roles, I've come to realize the cohort with the highest rejection rate is applicants to entry-level positions.&lt;/p&gt;

&lt;p&gt;What pains me to see is that most of them fall off the recruitment funnel for the simplest of mistakes, which often have nothing to do with their professional skills and could easily be avoided. These aren't failures of skill, but of communication.&lt;/p&gt;

&lt;p&gt;In this post, we will go over the developer recruitment process at&lt;br&gt;
&lt;a href="https://factorialhr.com"&gt;Factorial&lt;/a&gt;, mostly as an excuse for me to explain what is it that makes so many entry-level candidates flop their interviews, and how you can avoid it.&lt;/p&gt;
&lt;h2&gt;
  
  
  The process
&lt;/h2&gt;

&lt;p&gt;The recruitment process is simple: two interviews, one more generic &lt;em&gt;let's-meet&lt;/em&gt; type of interview, and another more technical. After the second meeting, you&lt;br&gt;
either get rejected or get a job offer.&lt;/p&gt;

&lt;p&gt;The first meeting is mostly innocuous: an opportunity for us and the candidate&lt;br&gt;
to assess whether we are a good match. The only piece of advice I can give you&lt;br&gt;
at this point is to be honest, not be a jerk and ask as many questions as you&lt;br&gt;
can. Ideally, you want to leave this encounter convinced whether you want this&lt;br&gt;
job or not. We will answer almost any question you might have, and you should be&lt;br&gt;
wary of any company that isn't willing to do the same.&lt;/p&gt;

&lt;p&gt;Once introductions have been made, you will be asked to submit a take-home&lt;br&gt;
exercise that will require you to write a representative chunk of your own&lt;br&gt;
code. If you are prolific enough, we will gladly accept another program you&lt;br&gt;
might have already developed. The second interview basically consists of you&lt;br&gt;
going through your own code with some devs from our tech team. You'll get asked&lt;br&gt;
technical questions about your submission and some more general aspects, if the&lt;br&gt;
conversation takes us down that path.&lt;/p&gt;

&lt;p&gt;The purpose of this exercise is many-fold, from evaluating general technical&lt;br&gt;
abilities to assessing reasoning capabilities but, mostly, the purpose of this&lt;br&gt;
exercise is to evaluate how well would you do the job we want you to do.  Most&lt;br&gt;
of these aspects are correlated, but if you fail at the latter you won't get&lt;br&gt;
hired.&lt;/p&gt;

&lt;p&gt;This is, unsurprisingly, where most candidates flop. Let's see why.&lt;/p&gt;
&lt;h2&gt;
  
  
  All candidates look alike
&lt;/h2&gt;

&lt;p&gt;Truth is, for entry-level positions, there's little variance in the candidates'&lt;br&gt;
technical skills.&lt;/p&gt;

&lt;p&gt;We get candidates with brilliant exercises that cannot defend it accordingly&lt;br&gt;
during the interview, candidates with lesser code that fair rather well during&lt;br&gt;
questioning, candidates obsessed with CS theory, others more of the&lt;br&gt;
learn-as-you-go type, variant degrees of experience, creativity,&lt;br&gt;
resourcefulness... In the end, all these aspects average out, painting the&lt;br&gt;
portrait of the default entry-level applicant who is capable of writing a fairly&lt;br&gt;
decent program involving frontend and backend code, sometimes with some extra&lt;br&gt;
sprinkles of infrastructure code on top.&lt;/p&gt;

&lt;p&gt;Put another way, statistics say that if you made it to the tech interview portion&lt;br&gt;
of the recruitment process you probably have the technical skillset required to get&lt;br&gt;
hired. This won't always be the case but, generally, the rule holds true.&lt;/p&gt;

&lt;p&gt;Now, if all candidates look alike, what is it that distinguishes them apart? What&lt;br&gt;
makes recruiters pick one over the many others?&lt;/p&gt;

&lt;p&gt;I'm convinced it's communication. More specifically, &lt;strong&gt;knowledge communication&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The success of a tech candidate is a function of their knowledge and how well&lt;br&gt;
they can communicate said knowledge.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Given that we have established most junior candidates have similar technical&lt;br&gt;
knowledge and that, unsurprisingly, most developers suck at communicating, you&lt;br&gt;
can see how this ends up with a high rejection rate of entry-level applicants.&lt;/p&gt;

&lt;p&gt;Let's explore further this notion of knowledge communication, and see how you can&lt;br&gt;
exploit it to improve your odds at your next tech interview.&lt;/p&gt;
&lt;h2&gt;
  
  
  Know your code
&lt;/h2&gt;

&lt;p&gt;Mind you, when I speak about communication I'm not implying you can talk your&lt;br&gt;
way through the recruitment process and end up at a cushy dev job with no&lt;br&gt;
technical skills to show for. At the tech interview, the beans will get spilled&lt;br&gt;
and your knowledge boundaries will be put to bare. Knowledge communication&lt;br&gt;
requires, well, knowledge; You have to do the work and learn your computer&lt;br&gt;
&lt;em&gt;sciency&lt;/em&gt; stuff first.&lt;/p&gt;

&lt;p&gt;Problem is, often developers spread their knowledge surface large and thin,&lt;br&gt;
sometimes too thin. They learn from repetition, which leads to a lack of&lt;br&gt;
understanding, which results in poor knowledge communication.&lt;/p&gt;

&lt;p&gt;Let's say you, as a candidate, learn about the new fancy framework &lt;em&gt;du jour&lt;/em&gt;,&lt;br&gt;
follow its documentation examples and, with today's tools, you quickly get a&lt;br&gt;
pretty decent app up and running. You already look like 99.9% of the other&lt;br&gt;
candidates. You even got &lt;em&gt;professional&lt;/em&gt; stuff out of the box: JSON Web Token&lt;br&gt;
authentication, cross-site scripting protection, WebSocket support, and whatnot.&lt;br&gt;
You start feeling confident and end up submitting an exercise that contains code&lt;br&gt;
that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApplicationController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;protect_from_forgery&lt;/span&gt; &lt;span class="ss"&gt;unless: &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&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="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is the candidate's code. If I &lt;code&gt;git blame&lt;/code&gt; it, their name will show up. And,&lt;br&gt;
yet, most entry-level candidates have but a vague idea what this code does.&lt;br&gt;
The result is candidates communicating their lack of knowledge about their own&lt;br&gt;
code. They cannot answer &lt;em&gt;what&lt;/em&gt; their software does and, what's worse, &lt;em&gt;why&lt;/em&gt; it&lt;br&gt;
does it.&lt;/p&gt;

&lt;p&gt;You have to know your code.&lt;/p&gt;

&lt;p&gt;To tackle this issue, I recommend candidates take a much more deliberate&lt;br&gt;
approach and think in terms of knowledge communication. If you are an applicant,&lt;br&gt;
run over every line of your exercise before you submit it and ask yourself: "Can&lt;br&gt;
I explain this line of code?". This will immediately beg questions about the&lt;br&gt;
&lt;em&gt;what&lt;/em&gt;, &lt;em&gt;why&lt;/em&gt;, and &lt;em&gt;how&lt;/em&gt; of every piece of your program you didn't really grasp,&lt;br&gt;
deepening your knowledge.&lt;/p&gt;

&lt;p&gt;What's more important, this approach will set you down a path of reinforced&lt;br&gt;
learning: Discovering how XSS protection works will take you through HTTP&lt;br&gt;
headers, the different types of HTTP verbs and codes, maybe you'll understand&lt;br&gt;
how your framework uses JWTs to manage your users' sessions and what this pesky&lt;br&gt;
CORS error is all about.&lt;/p&gt;

&lt;p&gt;At this point, you will arrive at the tech interview with knowledge not only on&lt;br&gt;
how to build a program with a particular framework, but on how the underlying&lt;br&gt;
infrastructure of the internet works to support the many features your framework&lt;br&gt;
provides and your app makes use of. You will be able to communicate your&lt;br&gt;
knowledge about your code and even respond to some extra curveballs the&lt;br&gt;
interviewer might throw at you. Your skills will be immediately more&lt;br&gt;
transferable, as all frameworks rely on the same underlying infrastructure.&lt;br&gt;
You'll be a better engineer.&lt;/p&gt;

&lt;p&gt;Sadly, you won't be able to answer everything, since the purpose of the tech&lt;br&gt;
interview is precisely to test the limits of your knowledge, so let's see what&lt;br&gt;
you can do about that.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Addendum: Other examples of poorly understood code I often encounter are JWTs,&lt;br&gt;
OAuth, Polymorphism, db indexes &amp;amp; foreign keys, HTTP basics, React component&lt;br&gt;
lifecycle methods, JS Promises, async/await &amp;amp; generators. You don't need to know&lt;br&gt;
all of these but, if it's in your code, you should.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Know your unknowns
&lt;/h2&gt;

&lt;p&gt;If you follow the aforementioned prescription, you'll quickly reach the second layer of your &lt;a href="https://fs.blog/2013/12/circle-of-competence/"&gt;circle of competence&lt;/a&gt;: things you know you don't understand very well.&lt;/p&gt;

&lt;p&gt;For example, you might feel brave and make use of the new &lt;code&gt;useEffect&lt;/code&gt; hook from React:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;CatCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&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="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counter&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="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="s2"&gt;`I have counted &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; cats so far!`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, &lt;code&gt;useEffect&lt;/code&gt; is hard — otherwise, its creator wouldn't have written a&lt;br&gt;
&lt;a href="https://overreacted.io/a-complete-guide-to-useeffect/"&gt;gazillion-line blog post&lt;/a&gt; about it — and you probably don't understand very well why you have to put that empty array as a second argument. You know, though, that if you don't the counter does not seem to refresh with every new cat you pass it as an argument. You have a thin knowledge of this piece of your code, and this is a problem.&lt;/p&gt;

&lt;p&gt;As a rule, do not try to hide your knowledge gaps in code. You'll open&lt;br&gt;
yourself to getting a question you will be playing guessing games against.&lt;br&gt;
Instead, simply admit it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;CatCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&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;// NOTE: I am not sure why I need this second argument but otherwise the&lt;/span&gt;
  &lt;span class="c1"&gt;// component does not seem to update on prop updates. Need to investigate.&lt;/span&gt;
  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counter&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="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="s2"&gt;`I have counted &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; cats so far!`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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



&lt;p&gt;Communicating a lack of knowledge is also knowledge communication.&lt;/p&gt;

&lt;p&gt;You are admitting your knowledge gap, implying you know this is a problem but had to move on with it, and announcing your intention to fix it. It shows self-awareness, curiosity and the drive to improve; the kind of potential we look for in candidates at this level. It’s not a simple “I don’t know”, which would be lazy, it’s a reasonable utilitarian argument that tacitly admits failure of understanding.&lt;/p&gt;

&lt;p&gt;At this point, the interviewer can do little more than ask if you had time to follow on your investigation which, given the circumstances, is an excellent outcome.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Addendum #2: Of course, if your exercise contains many comments like these you should reconsider whether you are ready to apply for the job. Nevertheless, do not be afraid to admit gray areas in your understanding.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Most entry-level candidates are very similar, and it’s highly unlikely you’ll be the exception. Instead, focus on deep knowledge vs thin understanding, specially about those concepts you know you might get questioned about. If you can, don’t answer only with “I don’t know” but don’t play guessing games either, state your knowledge gaps, what you think you know about them, and how you plan to improve on these gray areas.&lt;/p&gt;

&lt;p&gt;There are many more aspects we could explore in preparation for your first tech interviews, but these are the foundational aspects all candidates should be aware of. The rest, we'll explain in upcoming entries.&lt;/p&gt;

&lt;p&gt;Cheers, and good luck in your next interview.&lt;/p&gt;




&lt;p&gt;This post originally appeared at &lt;a href="https://gerardclos.com"&gt;https://gerardclos.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>developers</category>
      <category>codenewbie</category>
      <category>webdev</category>
      <category>career</category>
    </item>
    <item>
      <title>A set of programming aphorisms at Factorial</title>
      <dc:creator>Gerard</dc:creator>
      <pubDate>Wed, 15 Apr 2020 09:33:54 +0000</pubDate>
      <link>https://dev.to/factorial/a-set-of-programming-aphorisms-at-factorial-3j0m</link>
      <guid>https://dev.to/factorial/a-set-of-programming-aphorisms-at-factorial-3j0m</guid>
      <description>&lt;p&gt;At &lt;a href="https://factorialhr.com/"&gt;Factorial&lt;/a&gt;, we maintain an engineering Handbook where we document aspects such as common abstractions, programming principles and documentation of our architecture.&lt;/p&gt;

&lt;p&gt;Among these, there are a set of aphorisms stemming from coding best practices and common pitfalls we have been encountering during the last 4 years building our product. Let's share some of these.&lt;/p&gt;

&lt;p&gt;Beware, these aphorisms are language-agnostic and, thus, you might find them more or less regularly in your day to day depending on the characteristics of your preferred programming language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Depend on contracts rather than data structures
&lt;/h2&gt;

&lt;p&gt;This is my personal favorite because it's so simple yet so ubiquitous. Put&lt;br&gt;
bluntly, data structures make for &lt;a href="https://dev.to/factorial/some-reasons-to-avoid-hashes-in-ruby-and-some-alternatives-to-them-3j7n"&gt;lousy interfaces&lt;/a&gt;: they are often opaque, mutable and nullable, all characteristics you wouldn't want for an interface — and yet we use them as such constantly.&lt;/p&gt;

&lt;p&gt;The most common example is accepting a hash as a method argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:foo&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;:bar&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# This can print something, null or raise an unexpected error.&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;NOTE: This is especially prevalent in languages that make it easier to work with data structures and nullables such as Ruby or Javascript.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Using a data structure introduces an implicit dependency between your method and the data structure's shape, a dependency that could have been easily avoided by simply passing the expected value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;bar: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="c1"&gt;# This can print something or null&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In cases where the dependency with the data structure cannot be avoided, isolate it behind an API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;HashAccessor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:bar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# This can print something or null&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HashAccessor&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Although this might come across as a superfluous refactor it minimizes the spread of the dependency and paves the way for a future refactor in which we would get rid of this data structure dependency altogether.&lt;/p&gt;

&lt;h2&gt;
  
  
  Avoid null values
&lt;/h2&gt;

&lt;p&gt;Hardly a surprise. All the new &lt;a href="https://www.rust-lang.org/"&gt;cool kids&lt;/a&gt; in the block are using it.&lt;/p&gt;

&lt;p&gt;The problem with null values was already hinted at in the previous aphorism: it's a very hard contract to enforce. This will result in errors happening far away from the underlying issue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.rb&lt;/span&gt;
&lt;span class="no"&gt;ROLES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;admin: &lt;/span&gt;&lt;span class="s1"&gt;'admin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;manager: &lt;/span&gt;&lt;span class="s1"&gt;'manager'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ROLES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;role&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;user_presenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# user_presenter.rb&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;user_presenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'Admin'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;ROLES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="no"&gt;ManagerRolePresenter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# manager_role_presenter.rb&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;manager_role_presenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;capitalize&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; – Lead"&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;&amp;lt; Unexpected `capitalize` message for `nil`! This is very far from the origin of the `nil` and hard to fix&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To avoid null values you can enforce types (if your language supports it), implement the &lt;a href="https://doc.rust-lang.org/std/option/"&gt;optional pattern&lt;/a&gt;, use a custom contract with data validation (such as a Struct) or directly raise an exception closer to the null source.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code should be &lt;em&gt;greppable&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Or, put another way, do not be too smart for your own good.&lt;/p&gt;

&lt;p&gt;As a rule of thumb, your teammates should be able to easily navigate your code using only a pattern-matching tool like &lt;code&gt;grep&lt;/code&gt; (or &lt;code&gt;ctrl-f&lt;/code&gt; for those using fancier editors).&lt;/p&gt;

&lt;p&gt;If that weren't the case it probably means your code is not explicit enough and is hiding dependencies with dangerous techniques like meta-programming:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Jon&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Snow&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# main.rb&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;
    &lt;span class="s2"&gt;"Jon::&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constantize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="c1"&gt;# This can blow up&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As if the potential error wasn't bad enough, this technique obfuscates the&lt;br&gt;
author's intention and makes navigating your code more difficult than necessary.&lt;/p&gt;

&lt;p&gt;To avoid these pitfalls and improve code quality make extensive use of &lt;a href="https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis"&gt;static analysis tools&lt;/a&gt;&lt;br&gt;
such as linters or static type analysis.&lt;/p&gt;

&lt;p&gt;In the particular case of meta-programming, replace it with a good ol' Map or switch statement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Depend on abstractions rather concretions
&lt;/h2&gt;

&lt;p&gt;Lastly, a general principle. If you take a look at most of our previous examples and their proposed solutions, they all share a common property: the solution implements an abstraction.&lt;/p&gt;

&lt;p&gt;Do not depend on data structures, depend on an abstraction that gives you access to the underlying data. Do not depend on nullable values, depend on an abstraction that handles the nullable state for you... You can see the pattern.&lt;/p&gt;

&lt;p&gt;The advantage of abstractions over concretions is that they change less often, and this is good for code maintainability:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TFAfGF-b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kixnj602be1rptpr6t5f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TFAfGF-b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kixnj602be1rptpr6t5f.png" alt="Diagram changes v effects"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You often cannot control the amount of changes over time, but you can control the number of dependencies. Stay away from zone B and you will be fine.&lt;/p&gt;

&lt;p&gt;That's it! We hope you will find some useful tips from this list that you can put to good use in your daily coding practice.&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
    <item>
      <title>Some reasons to avoid Hashes in Ruby and some alternatives to them.</title>
      <dc:creator>Fran C.</dc:creator>
      <pubDate>Mon, 16 Mar 2020 08:23:28 +0000</pubDate>
      <link>https://dev.to/factorial/some-reasons-to-avoid-hashes-in-ruby-and-some-alternatives-to-them-3j7n</link>
      <guid>https://dev.to/factorial/some-reasons-to-avoid-hashes-in-ruby-and-some-alternatives-to-them-3j7n</guid>
      <description>&lt;p&gt;So, hashes, uh?&lt;/p&gt;

&lt;h3&gt;
  
  
  What's good about them?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;They are easy to build&lt;/li&gt;
&lt;li&gt;They are cheap (short-term cheap at least)&lt;/li&gt;
&lt;li&gt;They help interfacing with shapeless data (like JSON) in an easy way.&lt;/li&gt;
&lt;li&gt;They are good to build simple/cheap key-value stores in memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What's not so good about them?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;They are shapeless (in a bad way, you never know what you expect from them)&lt;/li&gt;
&lt;li&gt;They are mutable (in a bad way as well, how do you know nobody else will mutate this or nobody has already mutated it?)&lt;/li&gt;
&lt;li&gt;They are dummy (unlike objects, they know nothing, they have no way to interface with except for &lt;code&gt;Enumerable&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;They are impossible to type (🤷‍♂️)&lt;/li&gt;
&lt;li&gt;They need a lot of defensive code with &lt;code&gt;nil&lt;/code&gt; checks. (even when they are getting better at this with things like &lt;code&gt;hash.dig(:key1, :key2)&lt;/code&gt; it is not enough and you always need extra checks here and there, which makes the code difficult to read and to change).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  So, what should we do with them?
&lt;/h3&gt;

&lt;p&gt;I propose that we all agree on a small set of guidelines to help us answer the question "Should I use a &lt;code&gt;Hash&lt;/code&gt; for this?". TL;DR&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Avoid using Hashes as input to methods. Try to have shaped inputs.&lt;/li&gt;
&lt;li&gt;Avoid using Hashes as return values. Try to have shaped return values.&lt;/li&gt;
&lt;li&gt;If you receive a Hash, isolate it. Build a layer to interface with instead of the &lt;code&gt;Hash&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;Get the data directly if it is a small hash.&lt;/li&gt;
&lt;li&gt;Build objects if it has an heterogeneous structure.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  1. Avoid using hashes as input to methods.
&lt;/h4&gt;

&lt;p&gt;There's no easy way to know what's inside &lt;code&gt;params&lt;/code&gt; here..&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;MyInteractor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;params: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead use this:&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="no"&gt;MyInteractor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;value: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:value&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="ss"&gt;question_id: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:question_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You now have an explicit knowledge of the input for that interactor which is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;simpler to use (you don't need a Hash now, only values which can come from any object)&lt;/li&gt;
&lt;li&gt;Intention revealing&lt;/li&gt;
&lt;li&gt;Typable&lt;/li&gt;
&lt;li&gt;Easier to document&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try to avoid substituting the &lt;code&gt;Hash&lt;/code&gt; with a &lt;code&gt;T::Struct&lt;/code&gt; or a plain &lt;code&gt;Struct&lt;/code&gt; if you don't use sorbet. You will be adding an extra layer and having very little in return. You avoid the hash, which is good, but you add an extra layer and win very little in return. That does not justify a new layer.&lt;/p&gt;

&lt;p&gt;Instead, type the parameters you're receiving individually with Sorbet. If you don't use sorbet, just avoid the struct and pass them individually.&lt;/p&gt;

&lt;p&gt;You might think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But I have A TON of parameters and a &lt;code&gt;Hash&lt;/code&gt; is a nice and convenient way to&lt;br&gt;
make my object easier to use!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It isn't. You're sacrificing a lot in exchange for almost nothing and your code will suffer for it.&lt;/p&gt;

&lt;p&gt;Another reason to avoid this is that it can imply security holes. There's a very simple example which is mass assignment model attributes from the controller params.&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;# NOTE: This is not how our code works, this is an example of how NOT to do it&lt;/span&gt;
&lt;span class="n"&gt;current_user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_company&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;users&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:current_user&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;current_access&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can you spot the issue? It is subtle but it is there. An attacker could just send a &lt;code&gt;company_id&lt;/code&gt; and inject themselves on any company 😱. Not good.&lt;/p&gt;

&lt;p&gt;This kind of issue is what made Rails end up adding the strong parameters API: &lt;a href="https://guides.rubyonrails.org/action_controller_overview.html#strong-parameters"&gt;https://guides.rubyonrails.org/action_controller_overview.html#strong-parameters&lt;/a&gt; but that isn't enough. Strong parameters are focused on avoiding mass assignment. But you massively pass &lt;code&gt;params&lt;/code&gt; from a controller into any object as parameters you're exposed to this kind of problem as well.&lt;/p&gt;

&lt;p&gt;In short: Be as explicit as possible with contracts. Pass unfurled parameters as a preference and type as much as you can.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Avoid using hashes as return values.
&lt;/h4&gt;

&lt;p&gt;If whoever uses the code you write doesn't know what to expect from your return value, they'll have a hard time using you. Make it easy for them.&lt;/p&gt;

&lt;p&gt;If you need a dummy object, use a &lt;code&gt;T::Struct&lt;/code&gt; instead (or a &lt;code&gt;Struct&lt;/code&gt;). They are very good for transferring data, they have a defined shape and they are highly typable.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. If you receive a Hash, isolate it.
&lt;/h4&gt;

&lt;p&gt;Let's give an example, you get a &lt;code&gt;Hash&lt;/code&gt; from reading a YAML file, a JSON response from an API or even on a controller action.&lt;/p&gt;

&lt;p&gt;This is, by far, the hardest to solve among all the cases because each one will need a different solution.&lt;/p&gt;

&lt;p&gt;There are however some guidelines you can follow which help a bit:&lt;/p&gt;

&lt;h5&gt;
  
  
  1. Isolating hashes: Get their values
&lt;/h5&gt;

&lt;p&gt;If you only need to get some keys from the Hash, e.g. reading the &lt;code&gt;params&lt;/code&gt; on a controller. You're good to go. Slice the keys you need and then read them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
    &lt;span class="no"&gt;MyCreateInteractor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="n"&gt;current_access&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;value: &lt;/span&gt;&lt;span class="n"&gt;create_params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:value&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="ss"&gt;description: &lt;/span&gt;&lt;span class="n"&gt;create_params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:description&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unwrap!&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_params&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Soon we will be able to use sorbet for this, which will give use shaped and typed params. Until that moment arrives, we need to deal with it.&lt;/p&gt;

&lt;h5&gt;
  
  
  2. Isolating hashes: Build a defensive layer
&lt;/h5&gt;

&lt;p&gt;If the &lt;code&gt;Hash&lt;/code&gt; has layers with more hashes inside of it and you need to extract data from it through &lt;code&gt;Enumerable&lt;/code&gt; methods (&lt;code&gt;find&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;select&lt;/code&gt;...) then wrap that hash on an object and interface with that object instead.&lt;/p&gt;

&lt;p&gt;There's an example of this on our &lt;code&gt;PdfParser&lt;/code&gt; library. Its configuration is a YAML file with a shape like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;some_data_table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;min_x&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;55&lt;/span&gt;
  &lt;span class="na"&gt;min_y&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;111&lt;/span&gt;
  &lt;span class="na"&gt;max_x&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;532&lt;/span&gt;
  &lt;span class="na"&gt;max_y&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;167&lt;/span&gt;
  &lt;span class="na"&gt;transform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;table&lt;/span&gt;
    &lt;span class="na"&gt;arguments&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;column1&lt;/span&gt;
        &lt;span class="na"&gt;transform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text&lt;/span&gt;
        &lt;span class="na"&gt;max_x&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;214&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;column2&lt;/span&gt;
        &lt;span class="na"&gt;transform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text&lt;/span&gt;
        &lt;span class="na"&gt;max_x&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;372&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;column3&lt;/span&gt;
        &lt;span class="na"&gt;transform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;money_es&lt;/span&gt;
        &lt;span class="na"&gt;max_x&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;532&lt;/span&gt;

&lt;span class="na"&gt;some_numeric_field&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;min_x&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;217&lt;/span&gt;
  &lt;span class="na"&gt;min_y&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;81&lt;/span&gt;
  &lt;span class="na"&gt;max_x&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;265&lt;/span&gt;
  &lt;span class="na"&gt;max_y&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;99&lt;/span&gt;
  &lt;span class="na"&gt;transform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;money_es&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interfacing with a hash like this is problematic because you don't know what to expect. Have a look at the &lt;code&gt;transform&lt;/code&gt; for example. On the numeric field, it only has a name. But on the table; it has a type, a list of arguments and more nested transforms.&lt;/p&gt;

&lt;p&gt;Let's first understand the problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This file represents the format for a PDF file. A format has many different fields inside (&lt;code&gt;some_numeric_field&lt;/code&gt; and &lt;code&gt;some_data_table&lt;/code&gt; for example) in this case.&lt;/li&gt;
&lt;li&gt;Each field has boundaries to where it is found on the PDF&lt;/li&gt;
&lt;li&gt;Each field defines a transformation to be applied to it after reading the text on it. E.g.: &lt;code&gt;money_es&lt;/code&gt; means that it is money formatted like &lt;code&gt;1.000,00&lt;/code&gt; and it has to be transformed into a &lt;code&gt;BigDecimal&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How did we get over this? Interfacing with a &lt;code&gt;Hash&lt;/code&gt; like this could have been really complex so we started by separating the parts that change from the parts that stay the same.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All fields have boundaries&lt;/li&gt;
&lt;li&gt;All fields have a name&lt;/li&gt;
&lt;li&gt;All fields have a transform&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What is the changing part? The transform can be different per field so we defined something like this:&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="no"&gt;Field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:boundaries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:transform&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:min_x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:min_y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:max_x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:max_y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Transform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="c1"&gt;# @param args [Hash]&lt;/span&gt;
  &lt;span class="c1"&gt;# @option args [String, Hash] :transform the name of the transform or a&lt;/span&gt;
  &lt;span class="c1"&gt;#   Hash describing it&lt;/span&gt;
  &lt;span class="c1"&gt;# @option :transform [String] :type the name of the transform&lt;/span&gt;
  &lt;span class="c1"&gt;# @option :transform [Hash] :arguments a hash with the arguments for the&lt;/span&gt;
  &lt;span class="c1"&gt;#   transform&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;type&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="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:transform&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:transform&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:transform&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;:type&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:transform&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;:arguments&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that we build objects from reading the file into a Hash like this:&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;# name is the key of the YAML definition for a field and arguments is a hash&lt;/span&gt;
&lt;span class="c1"&gt;# with its content.&lt;/span&gt;
&lt;span class="n"&gt;read_file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&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="no"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="no"&gt;Transform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="no"&gt;Boundaries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:min_x&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:min_y&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:max_x&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:max_y&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We only read from the hash in 1 place (when parsing the configuration).&lt;/li&gt;
&lt;li&gt;We have a specific initializer for the case in which we need to pass a hash around (&lt;code&gt;Transform.from_hash&lt;/code&gt;) and we use a &lt;code&gt;case...when&lt;/code&gt; to map it into objects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is indeed more work but saves you from a lot of pain later on. Nobody will know this all came from a Hash, nobody will try to read a shapeless object and nobody will try to mutate it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Hashes good for?
&lt;/h2&gt;

&lt;p&gt;They are good as in-memory key-value stores. But even in that case, build a layer to isolate yourself from it. As an example:&lt;/p&gt;

&lt;p&gt;We use this object to store an in-memory cache of the hierarchical relations between employees and their managers. Fetching them is costly and because of our permissions architecture, we do it a lot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HierarchyCache&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# If a key has value, return it&lt;/span&gt;
  &lt;span class="c1"&gt;# if it doesn't store the return value of `block` and return the value&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch&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;employee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&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="n"&gt;get&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;employee&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;value&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt;

    &lt;span class="n"&gt;set&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;employee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# Get the value stored on a key&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&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;employee&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&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="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# Sore a value for a key&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;set&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;employee&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="n"&gt;new_cache_entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="vi"&gt;@cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;merge!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_cache_entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="vi"&gt;@cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_cache_entry&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;get&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;employee&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use a hash here but we take care of not letting anybody know we do and most importantly, we don't leak how the hash is structured and we provide a programmatic API to interface it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary (AKA TL;DR)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Avoid using Hashes as input to methods. Try to have shaped inputs.&lt;/li&gt;
&lt;li&gt;Avoid using Hashes as return values. Try to have shaped return values.&lt;/li&gt;
&lt;li&gt;If you receive a Hash, isolate it. Build a layer to interface with instead of the &lt;code&gt;Hash&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;Get the data directly if it is a small hash.&lt;/li&gt;
&lt;li&gt;Build objects if it has a heterogeneous structure.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use them as long as nobody can call &lt;code&gt;[]&lt;/code&gt; or any other &lt;code&gt;Enumerable&lt;/code&gt; method on them.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Last, but not least, don't serialize things into hashes if you intend to use them later on. If you find yourself using &lt;code&gt;[]&lt;/code&gt; on different layers of your code check if you can enforce any of the previous points.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summarized even more
&lt;/h2&gt;

&lt;p&gt;Don't use them to build contracts (as inputs/outputs). No problem as intermediate values (as long as you isolate them well enough).&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
    <item>
      <title>A handful of engineering principles at Factorial</title>
      <dc:creator>Pau Ramon Revilla</dc:creator>
      <pubDate>Tue, 18 Feb 2020 11:08:01 +0000</pubDate>
      <link>https://dev.to/factorial/a-handful-of-engineering-principles-at-factorial-344</link>
      <guid>https://dev.to/factorial/a-handful-of-engineering-principles-at-factorial-344</guid>
      <description>&lt;p&gt;I will be honest. The first prototype of &lt;a href="https://factorialhr.com"&gt;Factorial&lt;/a&gt; was built with Phoenix (Elixir). Nothing is more exciting to a crafter than to try a new tool. This one will be different, better perhaps. But it was not the time for tinkering: our goal was to launch Factorial's first version under one month. We threw the prototype to &lt;code&gt;/dev/null&lt;/code&gt; and turned to the tool we knew best, Ruby on Rails.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Spoiler: We launched our minimum viable product and successfully built a company around it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The most important priority for a technical founder is the speed of learning. You have a limited amount of time – let's be honest, cash in the bank – and you need to find product/market fit. But the biggest challenge is to learn fast while establishing a solid foundation, layering engineering principles to build upon. Nothing too specific nor rigid. Just a handful of concepts paired with some early abstractions that illustrate them. After all, the first lines of code you write will surely disappear, but the founding principles may prevail. Tweaked, twirled and twisted, but still there.&lt;/p&gt;

&lt;p&gt;So, what were those principles in Factorial?&lt;/p&gt;

&lt;h2&gt;
  
  
  First Principle: Verbs as first-class citizens
&lt;/h2&gt;

&lt;p&gt;Most programs are modeled after human language constructs. Objects are nouns and methods verbs.&lt;/p&gt;

&lt;p&gt;Hence, if we say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hellen rejects John's last time off request&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We tend to imagine the program like such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:time_off_requests&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;last_time_off_request&lt;/span&gt;
    &lt;span class="n"&gt;time_of_requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;last&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;rejects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time_off_request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time_off_request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;rejected: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;hellen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;email: &lt;/span&gt;&lt;span class="s1"&gt;'hellen@example.com'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;john&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;email: &lt;/span&gt;&lt;span class="s1"&gt;'john@example.com'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;hellen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rejects&lt;/span&gt; &lt;span class="n"&gt;john&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;last_time_off_request&lt;/span&gt; &lt;span class="c1"&gt;# Reads like english, yai!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With time you start to realize that this is the wrong way to go about it.&lt;br&gt;
As much as we feel nice and cozy when a program reads like English, it is not a good architectural principle. It's easy to confuse familiarity with good design.&lt;/p&gt;

&lt;p&gt;Rails abuses the English language metaphor. I've always been amazed that one of the pillars of the framework is the omnipresent &lt;a href="https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/inflections.rb"&gt;Inflector&lt;/a&gt;, a class that is responsible for the singular/plural forms which all the Rails conventions are based upon. And don't get me wrong, the English metaphor is probably one of the reasons Rails succeeded. It felt magical yet familiar to beginners, but in my experience, it falls apart in complex domains.&lt;/p&gt;

&lt;p&gt;In Rails &lt;em&gt;nouns&lt;/em&gt; are glorified and belong to the realms of &lt;code&gt;ActiveRecord&lt;/code&gt;. Please all stand-up and show respect to the king of all &lt;em&gt;subjects&lt;/em&gt;, the almighty &lt;code&gt;User&lt;/code&gt; model. After all, most sentences in your applications are in the form of &lt;code&gt;user &amp;lt;verb&amp;gt; &amp;lt;predicate&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But &lt;em&gt;verbs&lt;/em&gt;? They are an afterthought. To represent verbs we use methods in models and controllers. Both implementations are hard to reuse, one for being coupled to the database and the other with HTTP framework abstractions. And then you have strong parameters in the middle coupling both to make things worse.&lt;/p&gt;

&lt;p&gt;At Factorial we decided early on that we wanted verbs to be first-class citizens. When we explored a new domain we've asked ourselves which verbs would be part of it. We've resisted the temptation to model everything under CRUD/REST conventions and instead embrace domain-specific verbs. One does not say: "Hellen updates John's last time off request with rejected = false" but instead "Hellen rejects John's last time off request".&lt;/p&gt;

&lt;p&gt;We've implemented this by introducing a new type of object called the Interactor. This is not a new concept at all, but we've embraced it to the point that our applications do not look like a Rails application anymore: Our &lt;code&gt;ActiveRecord&lt;/code&gt; models are very small, they don't use any callbacks and most of the business logic is implemented on the Interactors instead. We've also removed the need for strong parameters since controllers never talk to &lt;code&gt;ActiveRecord&lt;/code&gt; directly. The verbs in our application are reusable, and more importantly, composable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Second Principle: Share memory, split domains
&lt;/h2&gt;

&lt;p&gt;We started Factorial at the peak of the microservices hype. "Microservices" encompassed a lot of different concepts, from scaling to organization topologies. Most of the ideas revolved around a very well known problem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As applications grow in size complexity increases exponentially making it harder to operate (for both machines and humans).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The microservices approach is to impose a paternalistic constraint on how to build software. It mostly bans shared memory so developers can't "cheat" the boundaries on their systems. Some people even go as far as to ban shared databases to keep domains completely isolated. By creating strict boundaries you ensure developers behave accordingly. We love constraint-based architectures but we wanted to explore another set of trade-offs. Can we have non-paternalistic boundaries?&lt;/p&gt;

&lt;p&gt;We've modeled our application as a monolith (sacrilege!) but separating each domain in a different engine. Those are our boundaries, soft but effective. No hardware constraints, no ban o shared memory and most importantly, no ban on shared databases. Our domain is highly relational so it is critical for us to be able to commit transactions across domains and sacrificing joins is not an option yet.&lt;/p&gt;

&lt;p&gt;It's the developer's job to ensure that boundaries are respected. I would be lying if I told you that we do. Sometimes we violate them knowingly (strictly speaking, incurring technical debt), others unknowingly. And yet, I believe the trade-off is a sweet spot for Factorial.&lt;/p&gt;

&lt;p&gt;Our rule of thumb is: "If we decide to remove this feature, how easy would it be to delete its code?". Optimizing for code removal early on has compounding benefits in the long run. And trust me, we've removed &lt;em&gt;a lot of features&lt;/em&gt; until finding product/market fit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Third Principle: Everything must be audited
&lt;/h2&gt;

&lt;p&gt;Some of the tools and techniques from the present are shaped by constraints from the past. This is very obvious when you work with relational databases. They were built with a space constraint that does not hold true anymore: Storage prices have decreased from $30,000/GB in 1989 to $0.019/GB in 2018 &lt;a href="https://en.wikipedia.org/wiki/Areal_density_(computer_storage)"&gt;source&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This constraint is the reason why most relational databases are mutable. They don't hold all the historical information. They update or delete rows when they are instructed to do so. A notable exception is the &lt;em&gt;binlog&lt;/em&gt; which is mostly used for replication purposes (although is becoming more common to connect it to a data sink to be able to gain back that information).&lt;/p&gt;

&lt;p&gt;We decided early on to store a record for each verb that was invoked. Yes, storage is cheap and we wanted to be as verbose as we could. We wanted to know what users have done with the system so we could solve their issues and eventually ask temporal questions: What was the salary of that given employee two months ago? Can you get all the contract changes in the last month?&lt;/p&gt;

&lt;p&gt;This turned out to be one of the most difficult but rewarding principles to implement. We've discovered that we could also use those audit events as a mechanism for domains to communicate with each other. Auditing events became the glue between the first and second principles. A verb triggers an event that can be listened to by another domain. Beautiful!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y_87nx3V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p-ef113b.f0.n0.cdn.getcloudapp.com/items/YEuAleRG/Image%2B2020-02-18%2Bat%2B10.41.14%2BAM.png%3Fv%3D5e188bc6df6a92daf04fec8831bcac6e" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y_87nx3V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p-ef113b.f0.n0.cdn.getcloudapp.com/items/YEuAleRG/Image%2B2020-02-18%2Bat%2B10.41.14%2BAM.png%3Fv%3D5e188bc6df6a92daf04fec8831bcac6e" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But this was actually not our invention. Without knowing it, we've stumbled upon Domain-Driven Design. Most of these concepts have been explored during the last decade: Verbs are shaped after the &lt;em&gt;ubiquitous language&lt;/em&gt;, domains are &lt;em&gt;bounded contexts&lt;/em&gt; and audit events are common among &lt;em&gt;event sourcing&lt;/em&gt; and &lt;em&gt;event storming&lt;/em&gt; practitioners.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The take here is that principles are important but must be vague enough. People joining your organization will come with new ideas. If they find rigid and strict principles they won't be able to influence the team. At Factorial we hire engineers from different backgrounds and it had a very positive effect on our engineering practices: Each developer has brought their own experiences from other languages and ecosystems and built new tools on top of those vague and flexible foundational principles. It's so enriching.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>domain</category>
      <category>principles</category>
      <category>ruby</category>
    </item>
    <item>
      <title>A trick with Ruby anonymous classes</title>
      <dc:creator>Fran C.</dc:creator>
      <pubDate>Fri, 14 Feb 2020 14:47:12 +0000</pubDate>
      <link>https://dev.to/factorial/a-trick-with-ruby-anonymous-classes-11pp</link>
      <guid>https://dev.to/factorial/a-trick-with-ruby-anonymous-classes-11pp</guid>
      <description>&lt;p&gt;Since everything in Ruby is an object it is only normal that classes are objects too. Which means they just have regular constructors with initializers, as any other object would do.&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="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Hello world!"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;

&lt;span class="c1"&gt;# prints -&amp;gt; Hello world!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What can I use it for?
&lt;/h3&gt;

&lt;p&gt;Anonymous classes are an amazing candidate for testing mixings.&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;# callable_test.rb&lt;/span&gt;
&lt;span class="c1"&gt;# run it with:&lt;/span&gt;
&lt;span class="c1"&gt;# ruby callable_test.rb&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Callable&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"minitest/autorun"&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestCallable&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Minitest&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Test&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setup&lt;/span&gt;
    &lt;span class="vi"&gt;@klass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;Callable&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@arg1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;
        &lt;span class="vi"&gt;@arg2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;@arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@arg2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_same_return&lt;/span&gt;
    &lt;span class="n"&gt;assert_equal&lt;/span&gt; &lt;span class="vi"&gt;@klass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="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="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@klass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&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="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Run options: --seed 3295&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# # Running:&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# .&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Finished in 0.000605s, 1651.9615 runs/s, 1651.9615 assertions/s.&lt;/span&gt;
&lt;span class="c1"&gt;# 1 runs, 1 assertions, 0 failures, 0 errors, 0 skips&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's a caveat though... You need to be aware that anonymous classes have no name (they are anonymous after all ;) ) so any call to &lt;code&gt;Class.new.name&lt;/code&gt; will return &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Classes only acquire a name when you assign them to a constant. That is:&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="n"&gt;klazz&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;klazz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;

&lt;span class="no"&gt;MyClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;klazz&lt;/span&gt;
&lt;span class="n"&gt;klazz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "MyClass"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, if you need to test things which depend on the class name you can't use anonymous classes, although they still have a benefit over regular declarations on tests, which is that they can be assigned to variables, while regular &lt;code&gt;class...end&lt;/code&gt; declarations can't.&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="n"&gt;my_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;my_class&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;

&lt;span class="n"&gt;other_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;OtherClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;other_class&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; OtherClass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, if you need a class with a name on a test you can still use this, only remember to remove the constant on your test's teardown.&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="no"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:remove_const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:MyClass&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're on a Rails app and use RSpec, it even has a helper to test things with anonymous controllers: &lt;a href="https://relishapp.com/rspec/rspec-rails/v/3-9/docs/controller-specs/anonymous-controller"&gt;https://relishapp.com/rspec/rspec-rails/v/3-9/docs/controller-specs/anonymous-controller&lt;/a&gt;, which is especially useful to test things like login/logout flows independently.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>testing</category>
    </item>
    <item>
      <title>A trick with Ruby Hash.new</title>
      <dc:creator>Fran C.</dc:creator>
      <pubDate>Wed, 12 Feb 2020 06:54:29 +0000</pubDate>
      <link>https://dev.to/factorial/a-trick-with-ruby-hash-new-2ma0</link>
      <guid>https://dev.to/factorial/a-trick-with-ruby-hash-new-2ma0</guid>
      <description>&lt;p&gt;Hashes are used a lot in Ruby (sometimes even abused) and they have a very interesting functionality that is rarely used: &lt;code&gt;Hash.new&lt;/code&gt; has 3 different forms&lt;/p&gt;

&lt;h2&gt;
  
  
  Regular form
&lt;/h2&gt;

&lt;p&gt;It just returns an empty hash whose unexisting keys return always &lt;code&gt;nil&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="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="c1"&gt;# Or h = {}&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:hello&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is just equivalent to using an empty Hash literal also known as &lt;code&gt;{}&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fixed default
&lt;/h2&gt;

&lt;p&gt;It allows for a parameter which is returned in case the key doesn't exist.&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="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'world'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:hello&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; 'world'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This form needs to be used carefully though since you always return the same object, which means if you modify it, you modify it for all subsequent calls:&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="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:hello&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;upcase!&lt;/span&gt; &lt;span class="c1"&gt;# "WORLD"&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:foo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# "WORLD"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is why only recommend using this option in a case: maps of classes.&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="no"&gt;POLICIES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ForbidAllPolicy&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="ss"&gt;admin: &lt;/span&gt;&lt;span class="no"&gt;AccessAllPolicy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;user: &lt;/span&gt;&lt;span class="no"&gt;RestrictedPolicy&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;POLICIES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;role&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="no"&gt;POLICIES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; RestrictedPolicy&lt;/span&gt;

&lt;span class="no"&gt;POLICIES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:hacker&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; ForbidAllPolicy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why classes but not other objects? Because classes are &lt;a href="https://refactoring.guru/design-patterns/singleton"&gt;singletons&lt;/a&gt; (a singleton is an object that only has one instance at the same time) so you do not care that you're always going to get the very same object all the time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calculated default
&lt;/h2&gt;

&lt;p&gt;This form gives the biggest freedom since it allows us to pass a block to calculate the value and even to store it on the hash. So the next call to that same key will already have a value.&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="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&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="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upcase&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"'&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' =&amp;gt; '&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;'"&lt;/span&gt;

  &lt;span class="nb"&gt;hash&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;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# prints -&amp;gt; 'hello' =&amp;gt; 'HELLO'&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "HELLO&lt;/span&gt;

&lt;span class="c1"&gt;# Next call to the same key is already assigned, the block isn't executed&lt;/span&gt;

&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "HELLO"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My preferred use case for this is to protect myself from &lt;code&gt;nil&lt;/code&gt;s and to avoid continuous &lt;code&gt;nil&lt;/code&gt; checks.&lt;/p&gt;

&lt;p&gt;In a case like this:&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="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:hello&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="ss"&gt;:world&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; NoMethodError (undefined method `&amp;lt;&amp;lt;' for nil:NilClass)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can either ensure the key is initialized&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="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:hello&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="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:hello&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="ss"&gt;:world&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; {:hello=&amp;gt;[:world]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or use the trick we just learned to ensure you will never have a &lt;code&gt;nil&lt;/code&gt; and you get a sane default instead.&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="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&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="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:hello&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="ss"&gt;:world&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; {:hello=&amp;gt;[:world]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take into account that passing around a Hash like this might be dangerous as well. Nobody will expect that a Hash returns something for a key that doesn't exist, it can be confusing and hard to debug.&lt;/p&gt;

&lt;p&gt;If we get &lt;code&gt;keys&lt;/code&gt; for the previous hash:&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="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; [:hello]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How to use it then? Just do not let the rest of the world know it is a Hash 😬&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CachedUser&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;CachedUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;

&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&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;# =&amp;gt; select * from users where id=1&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; &amp;lt;User: @id=1&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&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;# =&amp;gt; &amp;lt;User: @id=1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although the example is extremely simple it showcases how you can safely use a Hash as a container object safely without exposing some of its drawbacks but profiting from its flexibility.&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
    <item>
      <title>A trick with Ruby array literals</title>
      <dc:creator>Fran C.</dc:creator>
      <pubDate>Mon, 10 Feb 2020 09:49:24 +0000</pubDate>
      <link>https://dev.to/factorial/a-trick-with-ruby-array-literals-ha8</link>
      <guid>https://dev.to/factorial/a-trick-with-ruby-array-literals-ha8</guid>
      <description>&lt;p&gt;Declaring an array in Ruby is simple:&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="n"&gt;ary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"bar"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; ["foo", "bar"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but did you know you can save the array elements as variables the same time you declare them?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;ary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"bar"&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "foo"&lt;/span&gt;
&lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "bar"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks like magic? Well, it is not magic. This happens because assigning a value to a variable is an expression in Ruby. This is applicable to many other cases, like assigning a value on a conditional&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"User is &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or even crazier: to save the parameter you pass to a method!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;some_method&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="s2"&gt;"Hola"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# prints -&amp;gt; "Hola"&lt;/span&gt;

&lt;span class="n"&gt;value&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "Hola"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Disclaimer: ☝️ those 2 might be bad ideas. I wouldn't use it regularly on any code I write but knowing it is possible is always a good thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can I use this for?
&lt;/h2&gt;

&lt;p&gt;It plays quite well with constants that can then be used as some kind of enums:&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="no"&gt;COLORS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="no"&gt;COLOR_RED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="no"&gt;COLOR_BLUE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"BLUE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="no"&gt;COLOR_GREEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"GREEN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="no"&gt;COLOR_YELLOW&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"YELLOW"&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; ["RED", "BLUE", "GREEN", "YELLOW"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On rails apps they are especially useful to declare scopes:&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="n"&gt;scope&lt;/span&gt; &lt;span class="ss"&gt;:non_red&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;color: &lt;/span&gt;&lt;span class="no"&gt;COLORS&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;COLOR_RED&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="ss"&gt;:blue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;color: &lt;/span&gt;&lt;span class="no"&gt;COLOR_BLUE&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;



</description>
      <category>ruby</category>
      <category>rails</category>
    </item>
  </channel>
</rss>
