<?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: Alex Lion</title>
    <description>The latest articles on DEV Community by Alex Lion (@alexlion).</description>
    <link>https://dev.to/alexlion</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F145876%2F9b958e15-8d2c-4683-b81a-09a0e13acb63.png</url>
      <title>DEV Community: Alex Lion</title>
      <link>https://dev.to/alexlion</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alexlion"/>
    <language>en</language>
    <item>
      <title>What Makes Ruby Beautiful: Metaprogramming</title>
      <dc:creator>Alex Lion</dc:creator>
      <pubDate>Fri, 21 Aug 2020 20:57:02 +0000</pubDate>
      <link>https://dev.to/alexlion/what-makes-ruby-beautiful-metaprogramming-536a</link>
      <guid>https://dev.to/alexlion/what-makes-ruby-beautiful-metaprogramming-536a</guid>
      <description>&lt;p&gt;Ruby is one of the underrated programming languages among modern developers. It has become popular with the &lt;strong&gt;Ruby on Rails&lt;/strong&gt; framework.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ruby is making developers happy, productive and enjoying programming. - Yukihiro Matsumoto&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You are maybe coming from the JS world with a lot of frameworks or from Java and all its complexity.&lt;br&gt;
If you are enough of wasting your time building software that matter and want concrete result as soon as possible, let me introduce you to &lt;strong&gt;Ruby&lt;/strong&gt;.&lt;/p&gt;



&lt;p&gt;I'll introduce you to the concept of &lt;strong&gt;metaprogramming&lt;/strong&gt;.&lt;br&gt;
First time I learned Ruby, my &lt;strong&gt;mind literally blew&lt;/strong&gt; when I was confronted to this.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Think about a program that can generate program itself. A program that can generate executable code without the help of a developer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;No, it's not sci-fi, it's Ruby Metaprogramming !&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If I had to &lt;strong&gt;explain to a 5 years old&lt;/strong&gt;, imagine you want to draw a sunny city, you take your pen and write "Sunny City" on the paper. Push the button and magic happens. That's metaprogramming.&lt;/p&gt;

&lt;p&gt;Now, I'll explain to real developers.&lt;/p&gt;

&lt;p&gt;In Ruby, you can make runtime introspection on method. In another hand, you can ask an object about its capabilities (&lt;em&gt;Do you have this method?&lt;/em&gt;), its variables, constants and its class and ancestors.&lt;/p&gt;

&lt;p&gt;In this article I'll show you some examples with methods like &lt;strong&gt;respond_to?&lt;/strong&gt; (? is a Ruby convention for method returning a boolean) &lt;strong&gt;send&lt;/strong&gt; and &lt;strong&gt;define_method&lt;/strong&gt;. But there is a lot more like &lt;strong&gt;method_missing&lt;/strong&gt;, remove_method and &lt;strong&gt;undef_method&lt;/strong&gt;.&lt;br&gt;
I'll explain these 3 methods and finally show you the mind-blowing examples.&lt;/p&gt;
&lt;h1&gt;
  
  
  The respond_to?() method
&lt;/h1&gt;

&lt;p&gt;This method tests your class if it can handle a specific &lt;strong&gt;message&lt;/strong&gt;, for those who don't speak Ruby: it checks if a &lt;strong&gt;method&lt;/strong&gt; can be called in a specific class.&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%2Fbr56i7j329jc5qz6r3je.png" 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%2Fbr56i7j329jc5qz6r3je.png" alt="Message example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(In the Ruby vocabulary, message is known as a method).&lt;/p&gt;

&lt;p&gt;Here is a &lt;em&gt;Shipment&lt;/em&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Shipment&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;prepare_for_delivery&lt;/span&gt;
    &lt;span class="vi"&gt;@message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Shipment is prepared for delivery'&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;tracking_code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@tracking_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;code&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;Use the respond_to? method to check if prepare_for_delivery method exists:&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;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Shipment&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;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond_to?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:prepare_for_delivery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A more complete example sending a message, if this one exists, to another object.&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;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Shipment&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;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond_to?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:cancel_shipping&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cancel_shipping&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Oh no ! Shipment cannot be cancel."&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can be used for any 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="s1"&gt;'hello'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond_to?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="s1"&gt;'world'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond_to?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:include&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Did you catch it?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well, keep it in mind for the end of this article.&lt;/p&gt;

&lt;h1&gt;
  
  
  The send() method
&lt;/h1&gt;

&lt;p&gt;You can call any method in a class with the &lt;strong&gt;send()&lt;/strong&gt; 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="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Shipment&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;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond_to?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:tracking_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;s&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;:tracking_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'123ABC'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# or s.send('cancel_shipping', '123ABC')&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Tracking code is not available."&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;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%2Fm5i4v0oyg82ox59eyec5.png" 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%2Fm5i4v0oyg82ox59eyec5.png" alt="Message example 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(Message is sent in the first parameter of send())&lt;/p&gt;

&lt;p&gt;I'm hearing you saying: &lt;em&gt;"Why not calling our method directly ?"&lt;/em&gt;&lt;br&gt;
 &lt;br&gt;
Yes, we can and I know that this example is not a real world example on how we use it.&lt;/p&gt;

&lt;p&gt;Let's continue.&lt;/p&gt;
&lt;h1&gt;
  
  
  The define_method() method
&lt;/h1&gt;

&lt;p&gt;Now that you know the logic, you could even find the behavior of this method before I explain it to you.&lt;/p&gt;

&lt;p&gt;It… defines a method ? &lt;em&gt;Well done !&lt;/em&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Shipment&lt;/span&gt;
  &lt;span class="n"&gt;define_method&lt;/span&gt; &lt;span class="ss"&gt;:cancel&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="vi"&gt;@cancelled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;reason&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;You just defined a new method for the &lt;strong&gt;Shipment&lt;/strong&gt; class, setting an instance variable &lt;strong&gt;cancelled&lt;/strong&gt; to &lt;strong&gt;true&lt;/strong&gt; and printing the &lt;strong&gt;reason&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Wait, for the final example that will blow your mind.&lt;/p&gt;

&lt;h1&gt;
  
  
  Metaprogramming in one example
&lt;/h1&gt;

&lt;p&gt;You know the basics of Ruby metaprogramming, let's see the final example.&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%2Fg6652i0gbuyi5abljyqo.png" 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%2Fg6652i0gbuyi5abljyqo.png" alt="Cargo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's embark on the sea trip to metaprogramming and set sail !&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;# We create a container class. We only store the product's name at instantiation&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Container&lt;/span&gt;

  &lt;span class="kp"&gt;attr&lt;/span&gt; &lt;span class="ss"&gt;:product_name&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;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@product_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&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;# Apples ! Oranges ! All of theses fruits are contained in FruitContainer extending Container&lt;/span&gt;
&lt;span class="c1"&gt;# For simplification we only have one scanner&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FruitContainer&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Container&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;apples_scanner&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Scanning apples..."&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;# Potatoes ! Broccoli ! All of vegetables are contained in VegetableContainer extending Container&lt;/span&gt;
&lt;span class="c1"&gt;# For simplification we only have one scanner&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VegetableContainer&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Container&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;potatoes_scanner&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Scanning potatoes..."&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;# The Cargo containing all the containers&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cargo&lt;/span&gt;

  &lt;span class="c1"&gt;# The constructor accepting multiple parameters&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="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="c1"&gt;# self.class.send is used to define singleton methods for our class&lt;/span&gt;
      &lt;span class="c1"&gt;# we could also use define_singleton_method&lt;/span&gt;
      &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&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;:define_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"inspect_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;product_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="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;scanner_name&lt;/span&gt; &lt;span class="o"&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;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;product_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_scanner"&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond_to?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scanner_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;container&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="n"&gt;scanner_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
          &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"No scanner found."&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;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;potatoes_container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;VegetableContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="s2"&gt;"potatoes"&lt;/span&gt;
&lt;span class="n"&gt;apples_container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;FruitContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="s2"&gt;"apples"&lt;/span&gt;
&lt;span class="n"&gt;cargo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Cargo&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;potatoes_container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;apples_container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;cargo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect_apples&lt;/span&gt;
&lt;span class="n"&gt;cargo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect_potatoes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We used all the methods I explained. For each &lt;strong&gt;Container&lt;/strong&gt; classes, we define new methods which call a method (if exists) based on their product name, a scanner.&lt;/p&gt;

&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scanning apples...
Scanning potatoes...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Now, you know what metaprogramming is and how it works. Well done.&lt;/p&gt;

&lt;p&gt;One of the first uses case of metaprogramming is creating its own &lt;strong&gt;DSL&lt;/strong&gt; (Domain Specific Languages).&lt;/p&gt;

&lt;p&gt;There are some well-known tools based on the Ruby DSL, &lt;a href="https://www.chef.io/" rel="noopener noreferrer"&gt;Chef&lt;/a&gt; and &lt;a href="https://puppet.com/" rel="noopener noreferrer"&gt;Puppet&lt;/a&gt; for DevOps peoples.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is what makes Ruby beautiful.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Since I can't offer you a book on this topic, I'm replying to all your questions and feedback. &lt;a href="https://twitter.com/lnalx" rel="noopener noreferrer"&gt;Join me on Twitter !&lt;/a&gt;
&lt;/h4&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
    </item>
    <item>
      <title>Software Is Like Religions</title>
      <dc:creator>Alex Lion</dc:creator>
      <pubDate>Sun, 12 Jul 2020 08:21:15 +0000</pubDate>
      <link>https://dev.to/alexlion/software-is-like-religions-3a42</link>
      <guid>https://dev.to/alexlion/software-is-like-religions-3a42</guid>
      <description>&lt;p&gt;&lt;em&gt;3 reasons why developers sanctify technologies.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I recently post an article about React and VueJS.&lt;/p&gt;

&lt;p&gt;I explain why I choose React over VueJS. Yet, I posted a lot of articles about different topics on software engineering, but this last was my most popular one.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why ?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Do I have to conclude that &lt;em&gt;people&lt;/em&gt; are thirsty to know what’s the most important framework to choose between React and VueJS ?&lt;/p&gt;

&lt;p&gt;I learned React and VueJS and compared both, promoting React as the winner. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;But it isn’t.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It’s a point of view and some comparisons are more biased than another.&lt;/p&gt;

&lt;p&gt;I had 3 types of readers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The React enthusiast&lt;/strong&gt; saying: Yes man ! You choose the right side, React is
better !&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Vue enthusiast&lt;/strong&gt; saying: What the hell are you talking about ? It’s bullshit comparison.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The mature developer&lt;/strong&gt;: Choose whatever you can achieve your work with. There
is no winner.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a long time, I have been a technology enthusiast wanting to read, hear what I really want to read or hear. But I noticed that &lt;strong&gt;I was building a religion&lt;/strong&gt; around my favorite framework or whatever technology I used to.&lt;/p&gt;

&lt;p&gt;Here are the one of the &lt;strong&gt;3 characteristics&lt;/strong&gt; (not to say parodies) of a religion, applied to software.&lt;/p&gt;

&lt;h1&gt;
  
  
  Belief in Supernatural Features
&lt;/h1&gt;

&lt;p&gt;While some believing in a superior being, developers believe in superior features.&lt;/p&gt;

&lt;p&gt;We all believe that the product we use has incredible benefits, life-changing.&lt;/p&gt;

&lt;p&gt;We just need to look at some example of frameworks landing pages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--woI-tNf2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AeDwdsnSwhMHX-646RHnHgQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--woI-tNf2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AeDwdsnSwhMHX-646RHnHgQ.png" alt="" width="880" height="245"&gt;&lt;/a&gt;&lt;br&gt;
&lt;span&gt;&lt;a href="http://reactjs.org"&gt;reactjs.org&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3LTNXA5W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AnHubkglfHR2zdiFiEIdUIw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3LTNXA5W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AnHubkglfHR2zdiFiEIdUIw.png" alt="" width="880" height="125"&gt;&lt;/a&gt;&lt;br&gt;
&lt;span&gt;&lt;a href="http://vuejs.org"&gt;vuejs.org&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AEeIoACR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2Aiz0fFu4D5ghd_eOkS3QZqg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AEeIoACR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2Aiz0fFu4D5ghd_eOkS3QZqg.png" alt="" width="880" height="145"&gt;&lt;/a&gt;&lt;br&gt;
&lt;span&gt;&lt;a href="http://sorbet.org"&gt;sorbet.org&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fast&lt;/strong&gt;, &lt;strong&gt;scalable&lt;/strong&gt;, &lt;strong&gt;efficient&lt;/strong&gt;, &lt;strong&gt;beautiful&lt;/strong&gt;, &lt;strong&gt;incredible&lt;/strong&gt;, &lt;strong&gt;supernatural power&lt;/strong&gt;. All of them are incredible, there are no doubts!&lt;/p&gt;

&lt;p&gt;You can preach that VueJS is performant, it is ! Like any other frameworks…&lt;/p&gt;

&lt;p&gt;If you are a software architect, you know what you are playing for. &lt;em&gt;You cannot make mistakes&lt;/em&gt; when choosing a language, a framework or a tool.&lt;/p&gt;

&lt;p&gt;A fast and efficient technology could quickly become &lt;strong&gt;inefficient&lt;/strong&gt; and &lt;strong&gt;slow&lt;/strong&gt; if &lt;em&gt;you don’t know how to use it correctly&lt;/em&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Sacred vs Profane Technologies
&lt;/h1&gt;

&lt;p&gt;There are no sacred or profane objects, places or times. Just technologies you&lt;br&gt;
love and the others.&lt;/p&gt;

&lt;p&gt;When you choose one side, the other may appear to be the dark side. While it's a personal choice that &lt;strong&gt;fulfills your need&lt;/strong&gt; and  &lt;strong&gt;fit with your mindset&lt;/strong&gt; or &lt;strong&gt;ideology&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I saw so many articles on “X vs Y” or comments saying one is better than&lt;br&gt;
another. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Let's take a look at some HN comments&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4EsEyLfU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A7P3xtvqrBnaZ9rngep-mIA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4EsEyLfU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A7P3xtvqrBnaZ9rngep-mIA.png" alt="" width="720" height="224"&gt;&lt;/a&gt;&lt;br&gt;
&lt;span&gt;&lt;a href="https://news.ycombinator.com/item?id=18302162"&gt;https://news.ycombinator.com/item?id=18302162&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"React state propagation sucks."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Tough words.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Well done !&lt;/strong&gt; You just spot a Vue enthusiast.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BlDra-Mu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A2j3A54y9NQfnkJGm8OTfyg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BlDra-Mu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A2j3A54y9NQfnkJGm8OTfyg.png" alt="" width="712" height="416"&gt;&lt;/a&gt;&lt;br&gt;
&lt;span&gt;&lt;a href="https://news.ycombinator.com/item?id=11749203"&gt;https://news.ycombinator.com/item?id=11749203&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The last one is interesting, it’s one of the “third person” aka &lt;em&gt;the mature developer&lt;/em&gt; who knows his tools but still open-minded.&lt;/p&gt;

&lt;p&gt;Everybody has a reason to choose one over the other. After all, each person has the freewill to choose a religion as well.&lt;/p&gt;

&lt;p&gt;It shows that when we use a technology, &lt;em&gt;we try to find the same advantages on the other one&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;But very often that is not the case. It's a different paradigm. A new way of thinking or just built for a specific need. &lt;/p&gt;

&lt;p&gt;The world of software development has a lot of problems. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For each problem you can find one or multiple solutions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Good luck to find the one-which-fit-all.&lt;/p&gt;

&lt;h1&gt;
  
  
  A Community Bound Together by the Greatest
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Communities are powerful.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It’s the best place to find the best people&lt;/strong&gt;, the converted ones. They are the most competent peoples &lt;em&gt;who know almost everything about the tool.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When I tried Hasura as a GraphQL API, I was impressed by the 5000+ community members on Discord.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HJdZ3ltQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2ATUnGELVPui9_Dul5VM86eQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HJdZ3ltQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2ATUnGELVPui9_Dul5VM86eQ.png" alt="" width="880" height="629"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You are never alone.&lt;/p&gt;

&lt;p&gt;Meeting people who are using products in different environments and project is so satisfying !&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now, let’s talk about conferences.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ReactConf, VueConf, EmberConf, RubyConf, ElixirConf,&lt;br&gt;
&lt;em&gt;YourFavoriteFrameworkConf&lt;/em&gt;… &lt;/p&gt;

&lt;p&gt;Each technology community is built around conferences and meetups. It's the most enjoying part of the religion.&lt;/p&gt;

&lt;p&gt;Going in such a conference is the best way to find the gurus and connect with other peoples or companies who use the same tools.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;It’s like a Sunday service, for developers.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--El_cbJUy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AwpaIFuwEWBeqZ3So-sERtg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--El_cbJUy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AwpaIFuwEWBeqZ3So-sERtg.jpeg" alt="" width="880" height="476"&gt;&lt;/a&gt;&lt;br&gt;
&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@samuelpereira?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Samuel Pereira&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/tech-conference?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Being part of the community by using a tool can produce a real sense of belonging and motivate to contribute even more on the project.&lt;/p&gt;

&lt;h1&gt;
  
  
  Agnostic developers are rare.
&lt;/h1&gt;

&lt;p&gt;Now you see how software can easily become a religion, for some people.&lt;/p&gt;

&lt;p&gt;For passionate developers, as I am, it’s complicated to be agnostic and not evangelize what we use.&lt;/p&gt;

&lt;p&gt;Although, it is still important to use the right tool for the right job.&lt;/p&gt;

&lt;p&gt;If you want to build something out of your mind, &lt;strong&gt;choose a technology you know well&lt;/strong&gt;. You will go faster and have a better understanding / ownership of your code.&lt;/p&gt;

&lt;p&gt;If you want to find a job or for the love of learning new things, &lt;strong&gt;learn a trendy framework&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And remember: &lt;strong&gt;have fun to build products !&lt;/strong&gt; 🚀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>architecture</category>
      <category>developer</category>
      <category>technology</category>
    </item>
    <item>
      <title>Need Your Help to Build the Twitch for developers, designers and makers</title>
      <dc:creator>Alex Lion</dc:creator>
      <pubDate>Wed, 08 Jul 2020 11:58:11 +0000</pubDate>
      <link>https://dev.to/alexlion/need-your-help-to-build-the-twitch-for-developers-designers-and-makers-100m</link>
      <guid>https://dev.to/alexlion/need-your-help-to-build-the-twitch-for-developers-designers-and-makers-100m</guid>
      <description>&lt;p&gt;I dev.to community,&lt;/p&gt;

&lt;p&gt;A few weeks ago, I published a landing page for a project called Strow.io: &lt;a href="https://strow.io/"&gt;https://strow.io/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I realized that several developers, designers and makers livestream on Twitch or Youtube Live. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem is that these platforms are not suitable for them&lt;/strong&gt;. &lt;br&gt;
Youtube is for &lt;em&gt;entertainment&lt;/em&gt; and Twitch is for &lt;em&gt;gaming&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I've had a lot of people sign up on the landing and I've had a lot of encouragement. It's something that a lot of people are looking for and with a lot of potential.&lt;/p&gt;

&lt;p&gt;If I come here to talk to you about it, it's because today I have the vision of the project, I know the impact it can have.&lt;br&gt;
However, &lt;strong&gt;I cannot depend on Twitch or Youtube&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To monetize the platform I need to be independent.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The streaming infrastructure requires a lot of investment.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every time I push back the project, different people come to me to say "Alex, I need that ! It's really good."&lt;/p&gt;

&lt;p&gt;Today I'm solo, I always preferred to bootstrap my projects instead of finding investors. However, this kind of project is hardly bootstrapable.&lt;/p&gt;

&lt;p&gt;I need to hear the voice of the dev.to community.&lt;/p&gt;

&lt;p&gt;Do you think this idea is worth pursuing knowing that streaming is becoming more and more popular ?&lt;br&gt;
Do you have any advice or constructive feedback to offer?&lt;/p&gt;

&lt;p&gt;How to start small and with low investment in the livestream industry next to giants VC companies ? &lt;/p&gt;

&lt;p&gt;Thanks for your interest and your feedback 🙂&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>showdev</category>
      <category>help</category>
      <category>startup</category>
    </item>
    <item>
      <title>The Awesomeness of Azure Functions</title>
      <dc:creator>Alex Lion</dc:creator>
      <pubDate>Sun, 14 Jun 2020 07:52:22 +0000</pubDate>
      <link>https://dev.to/alexlion/the-awesomeness-of-azure-functions-3ael</link>
      <guid>https://dev.to/alexlion/the-awesomeness-of-azure-functions-3ael</guid>
      <description>&lt;p&gt;&lt;em&gt;FaaS, Fonction As A Service, is the new way to make your applications serverless.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If serverless is a new word for you, keep in mind that it’s like a microservice but smaller, &lt;strong&gt;processing only one task&lt;/strong&gt;. This service is executed every time you make a request.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bswHer4O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/5584/1%2A8iuYNNg5i9Z9P3pazkqmJg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bswHer4O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/5584/1%2A8iuYNNg5i9Z9P3pazkqmJg.png" alt="" width="880" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why I have to use a function instead of a standard service hosted in a server ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because hosting your own service involves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Waste of money&lt;/strong&gt;: For some processes, you don’t necessarily need a server running 24/24 7/7. With a FaaS, &lt;em&gt;you pay what you want&lt;/em&gt;, it’s “on demand”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stateful system&lt;/strong&gt;: States are horrible, it’s difficult to scale. &lt;em&gt;All your functions are stateless&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Operation’s nightmare&lt;/strong&gt;: Sometimes it’s difficult to sleep without worrying about the availability of our services. Serverless still need monitoring but you don’t have to worry about &lt;em&gt;scalability and availability&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, you know why serverless is cool. Especially with the &lt;a href="https://jamstack.org/"&gt;JAMStack&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To host your functions you have several providers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;AWS Lambda&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Azure Functions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Google Cloud Functions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IBM OpenWhisk&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenFaaS to build your own FaaS&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  AWS Lambda, the ancestor
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Amazon Web Services was the first to popularize FaaS with Lambda.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I started with AWS Lambda. To develop your functions you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use the embedded code editor: &lt;strong&gt;awful&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Develop on your local machine, zip the function and upload it with aws cli: &lt;strong&gt;awful&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send the zip directly from the user interface: &lt;strong&gt;awful&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The developer experience is terrible&lt;/strong&gt;. Testing your function is a nightmare and needs a lot of configurations.&lt;/p&gt;

&lt;p&gt;We don’t want to waste our money, and so our time.&lt;/p&gt;

&lt;p&gt;Moreover, AWS interface is so ugly with a bad UX (UI is OK but UX is more important for this kind of service).&lt;/p&gt;

&lt;p&gt;When I tried to calculate the cost of a project, Lambda was the more expensive one. It’s cheap if you connect your function to other AWS services, but when you need to go &lt;em&gt;outside of their system&lt;/em&gt;, they want your entire wallet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Azure Functions on my way
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;By comparing providers, I discovered Azure Functions.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I wasn’t keen on the idea of going with Microsoft.&lt;/p&gt;

&lt;p&gt;But I was impressed ! Of course we know that Microsoft is a real software company, and their Azure dashboard prove it.&lt;/p&gt;

&lt;p&gt;I didn’t struggle to find what I was looking for. &lt;strong&gt;Everything is intuitive&lt;/strong&gt;, so the UX.&lt;/p&gt;

&lt;p&gt;Calculating costs for your project is very easy with their calculator (AWS cost calculator has been released recently, too late).&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Azure Functions development workflow is life changing !
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;When I created a new function, Azure shows me all the steps to start developing my function:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;VS Code integration&lt;/strong&gt;, because it’s their product so they are taking advantage of it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Installing a NPM package&lt;/strong&gt; including the kit to develop our functions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;And all the workflow, inside VS Code !&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F8Uy4ZMY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2Ak6K6zTyZNimsNQAx" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F8Uy4ZMY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2Ak6K6zTyZNimsNQAx" alt="The how-to for Azure Functions development" width="585" height="838"&gt;&lt;/a&gt;&lt;em&gt;The how-to for Azure Functions development&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I developed, tested and deployed my function in an hour ! Compared to Lambda, it was day and night.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--37Ws2LZy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3352/1%2A_jI2oKHqNGwBZzu4rstWBw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--37Ws2LZy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3352/1%2A_jI2oKHqNGwBZzu4rstWBw.png" alt="Integration in VS Code" width="880" height="307"&gt;&lt;/a&gt;&lt;em&gt;Integration in VS Code&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Just after the deployment, Azure comes with the monitoring dashboard and explain you carefully how to use it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yva0CAJ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3792/1%2AplRNtJtQfMy3seXHZisZtw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yva0CAJ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3792/1%2AplRNtJtQfMy3seXHZisZtw.png" alt="Metrics dashboard" width="880" height="378"&gt;&lt;/a&gt;&lt;em&gt;Metrics dashboard&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Free tier is waiting for you, with open arms ;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try Functions&lt;/strong&gt;, it’s more worth than Lambda… if you don’t have an AWS architecture already in place.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>aws</category>
      <category>cloud</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Why Did I Quit Vue for React?</title>
      <dc:creator>Alex Lion</dc:creator>
      <pubDate>Sat, 30 May 2020 14:50:26 +0000</pubDate>
      <link>https://dev.to/alexlion/why-did-i-quit-vue-for-react-3h49</link>
      <guid>https://dev.to/alexlion/why-did-i-quit-vue-for-react-3h49</guid>
      <description>&lt;p&gt;The day I started modern front-end development, I made a decision every single developer are once doing in its life: &lt;strong&gt;choosing the right framework&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It was the time to stop making &lt;em&gt;ugly-unstructured-plain-old-javascript&lt;/em&gt; with jQuery.&lt;/p&gt;

&lt;p&gt;Let’s enter in the new era of the &lt;em&gt;trendy-shiny-popular-modular-javascript&lt;/em&gt; framework.&lt;/p&gt;

&lt;p&gt;So I choose VueJS.&lt;/p&gt;

&lt;p&gt;Here are the reasons why I loved (and still love) VueJs.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Keeping my precious HTML/CSS/JS structure at one place
&lt;/h2&gt;

&lt;p&gt;By far, the number one argument to sell VueJS, make it incredible.&lt;/p&gt;

&lt;p&gt;Vue files are very appealing for beginners.&lt;/p&gt;

&lt;p&gt;It’s simple to understand and easy to break your entire HTML template to Vue files.&lt;/p&gt;

&lt;p&gt;I can find out at a glance the structure (template), the behavior (script) and the look and feel (style).&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;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="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;myComponent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reading&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/template&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/Counter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;myComponent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&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="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;myDiv&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/style&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Vuex
&lt;/h2&gt;

&lt;p&gt;When I discovered how a state management system works, I started with Redux. It was hard to learn and seems to me over complicated.&lt;/p&gt;

&lt;p&gt;With Vuex, it was damn good.&lt;/p&gt;

&lt;p&gt;Only actions, mutations and stores are involved compared to actions, reducers and stores belonging to Redux. I didn’t catch reducers logic compared to mutations due to a lack of general knowledge when I discovered it or some bad learning resources I used.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For me, Vuex has been easier to start with for a newbie.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. NuxtJS
&lt;/h2&gt;

&lt;p&gt;To be honest, NuxtJS — inspired by the React NextJS — was my go-to-framework for a Vue project.&lt;/p&gt;

&lt;p&gt;I like the convention-over-configuration architecture of a Nuxt project.&lt;/p&gt;

&lt;p&gt;Pages are under page directory.&lt;/p&gt;

&lt;p&gt;Components in component directory.&lt;/p&gt;

&lt;p&gt;Store in store directory.&lt;/p&gt;

&lt;p&gt;Middleware in middleware directory and so one.&lt;/p&gt;

&lt;p&gt;All the injections are transparent. nuxt.config.js centralize all configurations. &lt;strong&gt;&lt;em&gt;Amazing !&lt;/em&gt;&lt;/strong&gt; It let you build SSR-enabled website and SPA without headaches.&lt;/p&gt;

&lt;h2&gt;
  
  
  But I give React a try (again)
&lt;/h2&gt;

&lt;p&gt;I didn’t tell you that before learning Vue I tried React but it was too brutal at first glance.&lt;/p&gt;

&lt;p&gt;My knowledge about how a state management works and knowing more about ES6 language specifications has changed.&lt;/p&gt;

&lt;p&gt;I saw plenty of articles even people around me are talking about React. So I give it a try.&lt;/p&gt;

&lt;p&gt;And it works. Enough to adopt the framework in my projects.&lt;/p&gt;

&lt;p&gt;Here is my point of view of the React's best benefits.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. ES6 and TypeScript friendly
&lt;/h2&gt;

&lt;p&gt;Developers know and master classes, interfaces and enumerations. It was why I was able to understand how React Components works and integrates in an application.&lt;/p&gt;

&lt;p&gt;You can use ES6 syntax as well with Vue but React is well more designed than Vue. Look at how you have to do to register components in React:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyComponent&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&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="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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For VueJS, you pass an object to the Vue Component function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;`&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore, modern React (today in 2020) doesn’t involve class anymore but functional component (and hooks).&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  TypeScript is making JavaScript great again. Just try it out, and you’ll like it.
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;p&gt;VueJs now offers TypeScript support. This support is not well polished like React using CRA (Create React App) with TS support &lt;strong&gt;in a single command&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For Vue, we still need some third-party packages with custom decorators and features to create a true, complete TypeScript application, and the official documentation does not include all the information you need to get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. JSX
&lt;/h2&gt;

&lt;p&gt;JSX is not evil.&lt;/p&gt;

&lt;p&gt;There are two schools: the pro-JSX and the anti-JSX. I don’t like to take a part of that conflict. JSX can be good or bad, it depends on how you want to work with your template.&lt;/p&gt;

&lt;p&gt;From my point of view, it is more logical for a developer minded to write JSX like&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;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;students&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;student&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;student&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;/p&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="err"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;than the more HTML-ish way of Vue&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="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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;student in students&lt;/span&gt;&lt;span class="dl"&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;student&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;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s a matter of preference, I find JSX more powerful and flexible.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Getting hook by hooks
&lt;/h2&gt;

&lt;p&gt;I started learning and developing with React Component. The problem is, to create a single component as a React Component class, it takes a lot of effort.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyComponent&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;render&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="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;Functional components let you use local state with hooks. It removes a lot of boilerplate and useless constructors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="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="nf"&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="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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;React Hooks simplify the use of state and other React parts like useEffect instead of &lt;em&gt;componentDidMount&lt;/em&gt; and &lt;em&gt;componentDidUpdate&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Some developers like the OOP approach by staying with classes, others the functional approach. &lt;strong&gt;You can use both in a project !&lt;/strong&gt;  🤙&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Community
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Behind great projects are great humans.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By experience, there is much more documentation, third-party tools and modules for React than Vue.&lt;/p&gt;

&lt;p&gt;I sometimes struggled by looking for Nuxt issues and found lots of Next (React) topics.&lt;/p&gt;

&lt;p&gt;By looking Github repos, numbers speak by themselves.&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%2Fcdn-images-1.medium.com%2Fmax%2F2076%2F1%2AwNQuTMRTGuxyCbfpQ0-pvg.png" 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%2Fcdn-images-1.medium.com%2Fmax%2F2076%2F1%2AwNQuTMRTGuxyCbfpQ0-pvg.png"&gt;&lt;/a&gt;&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%2Fcdn-images-1.medium.com%2Fmax%2F2006%2F1%2A7QYjobHdsszT4cyNHbp9kw.png" 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%2Fcdn-images-1.medium.com%2Fmax%2F2006%2F1%2A7QYjobHdsszT4cyNHbp9kw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or with their respective frameworks.&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%2Fcdn-images-1.medium.com%2Fmax%2F2032%2F1%2AEYhZee4k7j8mpPcrMH3D1Q.png" 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%2Fcdn-images-1.medium.com%2Fmax%2F2032%2F1%2AEYhZee4k7j8mpPcrMH3D1Q.png"&gt;&lt;/a&gt;&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%2Fcdn-images-1.medium.com%2Fmax%2F2026%2F1%2AxsBp7r8ni149q1lDFKpdrg.png" 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%2Fcdn-images-1.medium.com%2Fmax%2F2026%2F1%2AxsBp7r8ni149q1lDFKpdrg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Community leverage reliability of your code by solving bug fixes &lt;strong&gt;quicker&lt;/strong&gt;. Finding people with the same problem as you make your resolution fast therefore your shipping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vue 3 is coming…
&lt;/h2&gt;

&lt;p&gt;Vue is currently in version 2, version 3 is still in beta but there are a lot of big changes.&lt;/p&gt;

&lt;p&gt;One of them is the &lt;strong&gt;Composition API,&lt;/strong&gt; you can manage the state without Vuex and more cool things on the road!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;So, do I like VueJS ?&lt;/em&gt; Yes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Do I like React ?&lt;/em&gt; Yes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Is React better than Vue ?&lt;/em&gt; Matter of interest.&lt;/p&gt;

</description>
      <category>react</category>
      <category>vue</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Make your own S3 Object Storage</title>
      <dc:creator>Alex Lion</dc:creator>
      <pubDate>Wed, 06 Nov 2019 08:18:37 +0000</pubDate>
      <link>https://dev.to/alexlion/make-your-own-s3-object-storage-3487</link>
      <guid>https://dev.to/alexlion/make-your-own-s3-object-storage-3487</guid>
      <description>&lt;p&gt;The way media storage is stored today is completely different from several years ago.&lt;br&gt;
Cloud storage companies like &lt;strong&gt;Amazon&lt;/strong&gt; (AWS) or &lt;strong&gt;Microsoft&lt;/strong&gt; (Azure) have revolutionized the development and productivity of our applications.&lt;/p&gt;
&lt;h2&gt;
  
  
  Object Storage
&lt;/h2&gt;

&lt;p&gt;You can store everything in real life: data, DNA, paper, food, money… For each of these you have many ways to do it. You could store money in a wallet or in a bank account, it depends of your needs.&lt;/p&gt;

&lt;p&gt;It’s the same with data, the new gold mine of the 21st century. There is data everywhere, different support, different types. But what’s the best way to store them? Object storage is one solution for binary and media files.&lt;/p&gt;
&lt;h2&gt;
  
  
  Ceph
&lt;/h2&gt;

&lt;p&gt;Ceph stands out from data clustering technologies in the industry. Several big company use it in production as Cdiscount, Cisco, Bloomberg, Deutsche Telekom…&lt;/p&gt;

&lt;p&gt;Ceph offers several multi-level solutions: Object Storage, Block Storage, File System.&lt;br&gt;
We will focus on Object Storage.&lt;/p&gt;
&lt;h3&gt;
  
  
  Ceph architecture
&lt;/h3&gt;

&lt;p&gt;Before starting, it’s important to understand the philosophy behind Ceph. Here is an illustration of how the layers are decomposed: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PtDDvtpE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d33wubrfki0l68.cloudfront.net/824f66d72b4088a8a340a6fe0964675a2b48a5ad/cbdc3/img/uploads/1-mw28vrnvanc9xjiuf0tmtq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PtDDvtpE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d33wubrfki0l68.cloudfront.net/824f66d72b4088a8a340a6fe0964675a2b48a5ad/cbdc3/img/uploads/1-mw28vrnvanc9xjiuf0tmtq.png" alt="null" width="545" height="292"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need &lt;strong&gt;OSD&lt;/strong&gt; (Object Storage Daemons) containing our data, &lt;strong&gt;monitors&lt;/strong&gt; to analyze the health status of our OSDs and &lt;strong&gt;gateways&lt;/strong&gt; for the client access. &lt;/p&gt;

&lt;p&gt;We only use the &lt;strong&gt;Object Storage&lt;/strong&gt; interface, which allows us to use a gateway providing an API along with a &lt;strong&gt;S3 compatible&lt;/strong&gt; RestAPI (Amazon Simple Storage Service).&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating our storage cluster
&lt;/h2&gt;

&lt;p&gt;We need a dedicated client to orchestrate all our &lt;strong&gt;OSD&lt;/strong&gt;, &lt;strong&gt;MON&lt;/strong&gt; (monitors) and &lt;strong&gt;RGW&lt;/strong&gt; (Rados Gateway API S3) using &lt;strong&gt;ceph-deploy&lt;/strong&gt;.&lt;br&gt;
To ensure a sufficient quorum, we deployed 5 OSD/MON and RGW. Each OSD has 1GB of RAM, 4GB of disk space for the system and 33GB for the user data for a total of 198GB of storage replicated twice.&lt;br&gt;
Therefore, all our nodes are inspected with each other with the monitoring service. It is this service that is in charge of data recovery when an OSD is lost. When a client queries the S3 API, the API queries the interface that determines the location of the resource in the corresponding OSD or the location to save the resource.&lt;/p&gt;
&lt;h3&gt;
  
  
  Installing ceph-deploy
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user@ceph ~ # wget -q -O- ‘https://download.ceph.com/keys/release.asc' | sudo apt-key add –
user@ceph ~ # echo deb $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/ceph.list
user@ceph ~ # sudo apt update
user@ceph ~ # sudo apt install ceph-deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Once installed we can execute the commands in charge of installing Ceph on our whole cluster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r_V-tuzq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d33wubrfki0l68.cloudfront.net/4c43f7649864c0851b5b18d7003bb80e653da93a/1d94a/img/uploads/1-zdz6n2n2pcamoycv0gd_pw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r_V-tuzq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d33wubrfki0l68.cloudfront.net/4c43f7649864c0851b5b18d7003bb80e653da93a/1d94a/img/uploads/1-zdz6n2n2pcamoycv0gd_pw.png" alt="null" width="436" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On each machine we have to add a specific user for the installation of Ceph to ensure an isolation of the execution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user@ceph ~ # useradd -d /home/cephmgt -m cephmgt
user@ceph ~ # passwd cephmgt
user@ceph ~ # echo "cephmgt ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/cephmgt
user@ceph ~ # chmod 0440 /etc/sudoers.d/cephmgt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to allow SSH access to all the machines from the cluster we install the public key of our Ceph client and configure the SSH discovery by defining the user used for each host.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user@ceph ~ # ssh-keygen
user@ceph ~ # for i in {1..6}; do ssh-copy-id cephmgt@ceph0${i}; done
user@ceph ~ # cat .ssh/config
Host ceph01
  Hostname ceph01
  User ceph-mgt
…
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Data cluster
&lt;/h3&gt;

&lt;p&gt;All these steps to configure our cluster are made from our client host.&lt;br&gt;
For the creation of a new data cluster we create a new directory and then configure all our hosts as a member of our cluster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user@ceph ~ # mkdir my-clusteruser@ceph ~ # cd my-cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We define which host belong to our cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user@ceph ~ # ceph-deploy new ceph01 ceph02 ceph03 ceph04 ceph05 ceph06
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ceph binaries have to be installed in all the machines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user@ceph ~ # ceph-deploy install ceph01 ceph02 ceph03 ceph04 ceph05 ceph06
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A MON configuration file has to be created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user@ceph ~ # ceph-deploy mon create-initial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we deploy configuration accross the cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user@ceph ~ # ceph-deploy admin ceph01 ceph02 ceph03 ceph04 ceph05 ceph06
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To install monitor daemon on our hosts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user@ceph ~ # ceph-deploy mon add ceph01 ceph02 ceph03 ceph04 ceph05 ceph06
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we use all our machines has MON and OSD because of our cluster limited size for the demo. The best practice is to separate our MON and OSD to provide better availability.&lt;/p&gt;

&lt;p&gt;We create our OSDs and partition them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user@ceph ~ # ceph-deploy osd create ceph01:sdb ceph02:sdb ceph03:sdb ceph04:sdb ceph05:sdb ceph06:sdb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ceph will create partition on /dev/sdb for its journal (used to know where is the data) and the data itself.&lt;/p&gt;

&lt;p&gt;Finally, we create the S3 gateway on all our servers. The best practice still to have dedicated machine to play the role of gateway.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user@ceph ~ # ceph-deploy rgw create ceph01 ceph02 ceph03 ceph04 ceph05 ceph06
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GHyiDTos--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d33wubrfki0l68.cloudfront.net/c5d70b2edbbc50e3070dbb3a94217872d0a8689e/b0cb6/img/uploads/data_cluster_ceph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GHyiDTos--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d33wubrfki0l68.cloudfront.net/c5d70b2edbbc50e3070dbb3a94217872d0a8689e/b0cb6/img/uploads/data_cluster_ceph.png" alt="null" width="510" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Pool
&lt;/h2&gt;

&lt;p&gt;All our data are divided into pools, we must create a pool divided into several blocks (64 kb), with a size of 2, which means that data will be written twice in our cluster and minimum once in case of availability failures.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user@ceph ~ # ceph osd pool create my-userfiles 64
user@ceph ~ # ceph osd pool set my-userfiles size 2
user@ceph ~ # ceph osd pool set my-userfiles min_size 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  S3 API configuration (radosGW)
&lt;/h2&gt;

&lt;p&gt;Now that we have created our data store, we create a user linked to a bucket with 30 GB of quota.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user@ceph ~ # sudo radosgw-admin user create --uid="my-api" --display-name="My API"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are this message, it succeed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"user": "my-api","access_key": "XXXXXXXXXXXXX","secret_key": "XXXXXXXXXXXX"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we create permissions and quota:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user@ceph ~ # sudo radosgw-admin caps add --uid="supfile-api" --caps="users=*;buckets=*;metadata=*;usage=*;zone=*"
user@ceph ~ # sudo radosgw-admin quota set --uid="supfile-api" --quota-scope=bucket --max-size=30G
user@ceph ~ # sudo radosgw-admin quota enable --quota-scope=bucket --uid="supfile-api"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;From now on we can use our storage through the S3 Rest API.&lt;/p&gt;

&lt;p&gt;Ceph allows you to do a more lot of things as multisite replication, filesystem distribution, etc. &lt;/p&gt;

&lt;p&gt;This article shows the basics of Ceph but performance tunning and production usage are more complex, Ceph stays relatively complicated to install but offers a scalability and cost reduction in the long-term.&lt;/p&gt;

</description>
      <category>storage</category>
      <category>s3</category>
      <category>ceph</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
