<?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: Mehdi FARSI</title>
    <description>The latest articles on DEV Community by Mehdi FARSI (@farsi_mehdi).</description>
    <link>https://dev.to/farsi_mehdi</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%2F144710%2F026448b8-6603-41eb-ba57-4c32786c3d05.jpg</url>
      <title>DEV Community: Mehdi FARSI</title>
      <link>https://dev.to/farsi_mehdi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/farsi_mehdi"/>
    <language>en</language>
    <item>
      <title>Evolution of String since Ruby 1.8</title>
      <dc:creator>Mehdi FARSI</dc:creator>
      <pubDate>Tue, 10 Sep 2019 13:36:49 +0000</pubDate>
      <link>https://dev.to/farsi_mehdi/evolution-of-string-since-ruby-1-8-88m</link>
      <guid>https://dev.to/farsi_mehdi/evolution-of-string-since-ruby-1-8-88m</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vqc5l93m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1555685812-4b943f1cb0eb%3Fixlib%3Drb-1.2.1%26ixid%3DeyJhcHBfaWQiOjEyMDd9%26auto%3Dformat%26fit%3Dcrop%26w%3D3300%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vqc5l93m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1555685812-4b943f1cb0eb%3Fixlib%3Drb-1.2.1%26ixid%3DeyJhcHBfaWQiOjEyMDd9%26auto%3Dformat%26fit%3Dcrop%26w%3D3300%26q%3D80" alt="Evolution of Ruby String since 1.8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@farsi_mehdi/the-evolution-of-ruby-strings-from-1-8-to-2-5-8b2ed8f39fad"&gt;SEE MORE&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ruby</category>
      <category>rails</category>
      <category>coding</category>
    </item>
    <item>
      <title>Scope Gates in Ruby: Part II</title>
      <dc:creator>Mehdi FARSI</dc:creator>
      <pubDate>Thu, 05 Sep 2019 08:58:24 +0000</pubDate>
      <link>https://dev.to/farsi_mehdi/scope-gates-in-ruby-part-ii-2i4g</link>
      <guid>https://dev.to/farsi_mehdi/scope-gates-in-ruby-part-ii-2i4g</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i29D1FE5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/l6uj9aohb9q64u8y88eb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i29D1FE5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/l6uj9aohb9q64u8y88eb.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we use the &lt;code&gt;module&lt;/code&gt; keyword:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The value of &lt;code&gt;self&lt;/code&gt; changes&lt;/li&gt;
&lt;li&gt;The content of the module is embedded in an isolated scope&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/rubycademy/scope-gates-in-ruby-part-ii-e3c01ece9ad6"&gt;SEE MORE&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>programming</category>
      <category>coding</category>
    </item>
    <item>
      <title>The Inherited Hook Method in Ruby - and More Parenting Lessons</title>
      <dc:creator>Mehdi FARSI</dc:creator>
      <pubDate>Tue, 03 Sep 2019 13:53:39 +0000</pubDate>
      <link>https://dev.to/appsignal/the-inherited-hook-method-in-ruby-and-more-parenting-lessons-5ch7</link>
      <guid>https://dev.to/appsignal/the-inherited-hook-method-in-ruby-and-more-parenting-lessons-5ch7</guid>
      <description>&lt;p&gt;Hello children and parents, ahem Rubyists. In an earlier article, we dove into &lt;a href="https://blog.appsignal.com/2019/05/07/method-missing.html"&gt;the ancestry chain&lt;/a&gt;. In today's post, we'll dive deeper into parenting and inheritance. We will explore the inherited hook method and look into preventing inheritance.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Kids Inherit 101: The Inherited Hook Method
&lt;/h2&gt;

&lt;p&gt;Let's start with a look at how parenthood is declared. Ruby provides a neat way of interacting with a class when it is declared as the parent of another class.&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;Parent&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;inherited&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subclass&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;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;subclass&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; inherits from Parent"&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;class&lt;/span&gt; &lt;span class="nc"&gt;Child&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Parent&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Running this code prints out "Child inherits from Parent", as the &lt;code&gt;Parent.inherited&lt;/code&gt; method is called when the &lt;code&gt;Child&lt;/code&gt; class inherits from &lt;code&gt;Parent&lt;/code&gt;. Note that this method takes the subclass as parameter—&lt;code&gt;Child&lt;/code&gt;, in our case. This mechanism allows you to interact with the Parent class to define a set of behaviors only if it is inherited. By behavior, in this context, we mean modifying, defining or deleting variables, methods and constants on the inheriting or the inherited class.&lt;/p&gt;

&lt;p&gt;Now, let's define the &lt;code&gt;parent_name&lt;/code&gt; method on-the-fly:&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;Parent&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;inherited&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subclass&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;subclass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_method&lt;/span&gt; &lt;span class="ss"&gt;:parent_name&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="s2"&gt;"Daddy"&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;class&lt;/span&gt; &lt;span class="nc"&gt;Child&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Parent&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Child&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;parent_name&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "Daddy"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here, we define a method on the &lt;code&gt;Child&lt;/code&gt; class when it inherits from the &lt;code&gt;Parent&lt;/code&gt; class, but without adding that method directly to the &lt;code&gt;Parent&lt;/code&gt; class. Instead, it's only defined when another class inherits from &lt;code&gt;Parent&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Alright, we've covered the theory, now let’s take a look at a more realistic example in the life of a Rubyist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prevent Class Inheritance
&lt;/h2&gt;

&lt;p&gt;In Ruby on Rails, database migrations are handled by the &lt;code&gt;ActiveRecord::Migration&lt;/code&gt; class. Let’s try to directly inherit from this class.&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;AddFirstnameToUsers&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Migration&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# =&amp;gt; StandardError (Directly inheriting from ActiveRecord::Migration is not supported..)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This error is raised because Ruby on Rails provides a mechanism that prevents us from inheriting from this class. So why did Ruby on Rails implement this mechanism?&lt;/p&gt;

&lt;p&gt;A migration is strongly coupled to a specific version of Ruby on Rails. Indeed, the API provided by this class can slightly change between 2 versions. So, to avoid breaking migrations when you upgrade Ruby on Rails, the framework forces you to choose a specific version of the ActiveRecord::Migration class. This ensures the smooth running of your migrations.&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;AddFirstnameToUsers&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Migration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;4.2&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;In the example above, our migration is coupled to the &lt;code&gt;ActiveRecord::Migration&lt;/code&gt; API provided with version 4.2 of Ruby on Rails. So, even if we upgrade our application to version 5.0, our migrations will still run smoothly because they'll still run with version 4.2 of the &lt;code&gt;ActiveRecord::Migration&lt;/code&gt; API.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Preventing Inheritance Works
&lt;/h2&gt;

&lt;p&gt;Now that we understand &lt;strong&gt;why&lt;/strong&gt; inheritance is prevented here, let’s see &lt;strong&gt;how&lt;/strong&gt; this &lt;code&gt;ActiveRecord::Migration&lt;/code&gt; prevents inheritance. All the logic is defined in the &lt;code&gt;ActiveRecord::Migration.inherited&lt;/code&gt; method.&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;AddFirstnameToUsers&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Migration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;4.2&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;When our &lt;code&gt;AddFirstnameToUsers&lt;/code&gt; class inherits from &lt;code&gt;ActiveRecord::Migration&lt;/code&gt;, the &lt;code&gt;ActiveRecord::Migration.inherited&lt;/code&gt; hook method is called.&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;ActiveRecord&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Migration&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;inherited&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subclass&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;#:nodoc:&lt;/span&gt;
      &lt;span class="k"&gt;super&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;subclass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;superclass&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;Migration&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="no"&gt;StandardError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Directly inheriting from ActiveRecord::Migration is not supported. "&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;
          &lt;span class="s2"&gt;"Please specify the Rails release the migration was written for:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;
          &lt;span class="s2"&gt;"  class &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;subclass&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt; ActiveRecord::Migration[4.2]"&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As we can see, this hook method checks if the subclass (&lt;code&gt;AddFirstnameToUsers&lt;/code&gt;) directly inherits from &lt;code&gt;ActiveRecord::Migration&lt;/code&gt;. If it does, an error is raised. This is the perfect entry point for controlling inheritance.&lt;/p&gt;

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

&lt;p&gt;Today, we covered the basics of inheritance and preventing inheritance. We covered the inherited hook method and saw how it can be very handy when interacting with the inheriting/inherited class on-the-fly.&lt;/p&gt;

&lt;p&gt;In a real-world setting, watch out when playing with inheritance. Be very cautious when you remove or override an existing method or class. This could result in some unwanted side effects. Children may stop calling you daddy.&lt;/p&gt;

&lt;p&gt;Et Voilà, this concludes our post for today!&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>learning</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The guide to enjoy your first developer job</title>
      <dc:creator>Mehdi FARSI</dc:creator>
      <pubDate>Tue, 03 Sep 2019 11:38:59 +0000</pubDate>
      <link>https://dev.to/farsi_mehdi/the-guide-to-enjoy-your-first-developer-job-5b3h</link>
      <guid>https://dev.to/farsi_mehdi/the-guide-to-enjoy-your-first-developer-job-5b3h</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l0zYTvwk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cz73ngj9d69w2zp9h426.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l0zYTvwk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cz73ngj9d69w2zp9h426.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This guide will give you the tools to get the best of your future developer job.. &lt;a href="https://medium.com/@farsi_mehdi/the-guide-to-enjoy-your-first-developer-job-7cc8c2abd8e0?source=friends_link&amp;amp;sk=a9ff524a57eb08d67a7ab2d4dd9de603"&gt;SEE MORE&lt;/a&gt;&lt;/p&gt;

</description>
      <category>job</category>
      <category>programming</category>
      <category>startup</category>
    </item>
    <item>
      <title>Magic comments in Ruby</title>
      <dc:creator>Mehdi FARSI</dc:creator>
      <pubDate>Thu, 15 Aug 2019 08:29:43 +0000</pubDate>
      <link>https://dev.to/farsi_mehdi/magic-comments-in-ruby-gg0</link>
      <guid>https://dev.to/farsi_mehdi/magic-comments-in-ruby-gg0</guid>
      <description>&lt;p&gt;In this article, we’re going to explore the following topics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;comments vs magic comments&lt;/li&gt;
&lt;li&gt;specifications&lt;/li&gt;
&lt;li&gt;existing magic comments&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@farsi_mehdi/magic-comments-in-ruby-81d45ff92e34"&gt;SEE MORE&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
    </item>
    <item>
      <title>Up the Ruby Ancestor Chain with method_missing</title>
      <dc:creator>Mehdi FARSI</dc:creator>
      <pubDate>Wed, 08 May 2019 10:50:30 +0000</pubDate>
      <link>https://dev.to/appsignal/up-the-ruby-ancestor-chain-with-methodmissing-35f</link>
      <guid>https://dev.to/appsignal/up-the-ruby-ancestor-chain-with-methodmissing-35f</guid>
      <description>&lt;p&gt;Clutch your carry-on luggage, because today we'll travel all the way up the ancestor chain. We'll follow a method call and see how it goes up the chain as well as find out what happens if the method is missing. And because we love to play with fire, we won't stop there but continue on to &lt;del&gt;playing with fire&lt;/del&gt; overriding the &lt;code&gt;BasicObject#method_missing&lt;/code&gt;. If you pay attention, we might also use it in a practical example. No guarantees though. Let's go!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Ancestor Chain
&lt;/h2&gt;

&lt;p&gt;Let's start with the fundamental rules of ancestor chains in Ruby:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby only supports single inheritance&lt;/li&gt;
&lt;li&gt;It also allows an object to include a set of modules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Ruby, the ancestor chain is composed of the traversal of all the inherited classes and modules for a given class.&lt;/p&gt;

&lt;p&gt;Let’s have a look at an example to show you how the ancestor chain is handled in Ruby.&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;Auth&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Session&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Iterable&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;Collection&lt;/span&gt;
  &lt;span class="n"&gt;prepend&lt;/span&gt; &lt;span class="no"&gt;Iterable&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;Users&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Collection&lt;/span&gt;
  &lt;span class="n"&gt;prepend&lt;/span&gt; &lt;span class="no"&gt;Session&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Auth&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ancestors&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;produces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="no"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Auth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;# Users&lt;/span&gt;
  &lt;span class="no"&gt;Iterable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;# Collection&lt;/span&gt;
  &lt;span class="no"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Kernel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;BasicObject&lt;/span&gt;  &lt;span class="c1"&gt;# Ruby Object Model&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;First, we call the &lt;code&gt;ancestors&lt;/code&gt; class method to access the ancestor chain of a given class.&lt;/p&gt;

&lt;p&gt;We can see that a call to &lt;code&gt;Users.ancestors&lt;/code&gt; returns an array of classes and modules that contain, in order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The prepended modules of &lt;code&gt;Users&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Users&lt;/code&gt; class&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Users&lt;/code&gt; class’ included modules&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Collection&lt;/code&gt; class’ prepended modules — as the direct parent of Users&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Collection&lt;/code&gt; class&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Collection&lt;/code&gt; class’ included modules — none&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Object&lt;/code&gt; class — the default inheritance of any class&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Kernel&lt;/code&gt; module — included in &lt;code&gt;Object&lt;/code&gt; and holding core methods&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;BasicObject&lt;/code&gt; class — the root class in Ruby&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, the order of appearance for a given traversed class or module is always as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The prepended modules&lt;/li&gt;
&lt;li&gt;The class or module&lt;/li&gt;
&lt;li&gt;Its included modules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The ancestor chain is mainly traversed by Ruby when a method is invoked on an object or a class.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Method Lookup Path
&lt;/h2&gt;

&lt;p&gt;When a message is sent, Ruby traverses the ancestor chain of the message receiver and checks if any of them responds to the given message.&lt;/p&gt;

&lt;p&gt;If a given class or module of the ancestor chain responds to the message, then the method associated with this message is executed and the ancestor chain traversal is stopped.&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;Collection&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ancestors&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; [Collection, Array, Enumerable, Object, Kernel, BasicObject]&lt;/span&gt;

&lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Collection&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;:a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:c&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_with_index&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; :a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here, the &lt;code&gt;collection.each_with_index&lt;/code&gt; message is received by the Enumerable module. Then the &lt;code&gt;Enumerable#each_with_index&lt;/code&gt; method is called for this message.&lt;/p&gt;

&lt;p&gt;Here, when &lt;code&gt;collection.each_with_index&lt;/code&gt; is called, Ruby checks if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Collection responds to the &lt;code&gt;each_with_index message&lt;/code&gt; =&amp;gt; &lt;strong&gt;NO&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Array responds to the &lt;code&gt;each_with_index message&lt;/code&gt; =&amp;gt; &lt;strong&gt;NO&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Enumerable responds to the &lt;code&gt;each_with_index message&lt;/code&gt; =&amp;gt; &lt;strong&gt;YES&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, from here, Ruby stops the ancestor chain traversal and calls the method associated with this message. In our case, the &lt;code&gt;Enumerable#each_with_index&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;In Ruby, this mechanism is called the &lt;em&gt;Method Lookup Path&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now, what happens if none of the classes and modules that compose a given receiver’s ancestor chain respond to the message?&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;BasicObject#method_missing&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Enough with playing nice! Let's break things, developer style: by throwing exceptions. We'll implement a &lt;code&gt;Collection&lt;/code&gt; class and call an unknown method on one of its instances.&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;Collection&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Collection&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;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'item1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; NoMethodError: undefined method `search` for #&amp;lt;Collection:0x123456890&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here, the &lt;code&gt;Collection&lt;/code&gt; class doesn't implement a &lt;code&gt;search&lt;/code&gt; method. So a &lt;code&gt;NoMethodError&lt;/code&gt; is raised. But where does this error raising comes from?&lt;/p&gt;

&lt;p&gt;The error is raised in the &lt;code&gt;BasicObject#method_missing&lt;/code&gt; method. This method is called when the &lt;em&gt;Method Lookup Path&lt;/em&gt; ends up not finding any method corresponding to a given message.&lt;/p&gt;

&lt;p&gt;Okay... but this method only raises a &lt;code&gt;NoMethodError&lt;/code&gt;. So it would be great to be able to override the method in the context of our &lt;code&gt;Collection&lt;/code&gt; class.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overriding the &lt;code&gt;BasicObject#method_missing&lt;/code&gt; Method
&lt;/h2&gt;

&lt;p&gt;Guess What? It’s totally fine to override &lt;code&gt;method_missing&lt;/code&gt; as this method is also subject to the mechanism of &lt;em&gt;Method Lookup Path&lt;/em&gt;. The only difference with a normal method is that we’re sure that this method will be found at least once by the &lt;em&gt;Method Lookup Path&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Indeed, the &lt;code&gt;BasicObject class&lt;/code&gt; — which is the root class of any class in Ruby — defines a minimal version of this method. Classic Ruby Magic, n'est pas?&lt;/p&gt;

&lt;p&gt;So let’s override this method in our &lt;code&gt;Collection class&lt;/code&gt;:&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;Collection&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;@collection&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method_missing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_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;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;method_id&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&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;method_id&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="vi"&gt;@collection&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="nf"&gt;to_sym&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;first&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="vi"&gt;@collection&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;method_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="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Collection&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;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;obj1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'value1'&lt;/span&gt;
&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;obj2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'value2'&lt;/span&gt;

&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;obj1&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; 'value1'&lt;/span&gt;
&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;obj2&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; 'value2'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here, the &lt;code&gt;Collection#method_missing&lt;/code&gt; acts as a delegator to the &lt;code&gt;@collection&lt;/code&gt; instance variable. Actually, this is the way Ruby roughly handles object delegation — c.f: the &lt;code&gt;delegate&lt;/code&gt; library.&lt;/p&gt;

&lt;p&gt;If the missing method is a setter method (&lt;code&gt;collection.obj1 = 'value1'&lt;/code&gt;), then the method name (&lt;code&gt;:obj1&lt;/code&gt;) is used as the key and the argument (&lt;code&gt;'value1'&lt;/code&gt;) as the value of the &lt;code&gt;@collection&lt;/code&gt; hash entry (&lt;code&gt;@collection[:obj1] = 'value1'&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  An HTML Tag Generator
&lt;/h2&gt;

&lt;p&gt;Now that we know how the &lt;code&gt;method_missing&lt;/code&gt; method works behind the scenes, let’s implement a reproducible use case.&lt;/p&gt;

&lt;p&gt;Here, the goal is to define the following DSL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;HTML&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;p&lt;/span&gt;    &lt;span class="s1"&gt;'hello world'&lt;/span&gt;             &lt;span class="c1"&gt;# =&amp;gt; &amp;lt;p&amp;gt;hello world&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="no"&gt;HTML&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;div&lt;/span&gt;  &lt;span class="s1"&gt;'hello world'&lt;/span&gt;             &lt;span class="c1"&gt;# =&amp;gt; &amp;lt;div&amp;gt;hello world&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="no"&gt;HTML&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;h1&lt;/span&gt;   &lt;span class="s1"&gt;'hello world'&lt;/span&gt;             &lt;span class="c1"&gt;# =&amp;gt; &amp;lt;h1&amp;gt;hello world&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="no"&gt;HTML&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;h2&lt;/span&gt;   &lt;span class="s1"&gt;'hello world'&lt;/span&gt;             &lt;span class="c1"&gt;# =&amp;gt; &amp;lt;h2&amp;gt;hello world&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="no"&gt;HTML&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span&lt;/span&gt; &lt;span class="s1"&gt;'hello world'&lt;/span&gt;             &lt;span class="c1"&gt;# =&amp;gt; &amp;lt;span&amp;gt;hello world&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="no"&gt;HTML&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;p&lt;/span&gt;    &lt;span class="s2"&gt;"hello &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;HTML&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b&lt;/span&gt; &lt;span class="s1"&gt;'world'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; &amp;lt;p&amp;gt;hello &amp;lt;b&amp;gt;world&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To do so, we’re going to implement the &lt;code&gt;HTML.method_missing&lt;/code&gt; method in order to avoid defining a method for each HTML tag.&lt;/p&gt;

&lt;p&gt;First, we define an &lt;code&gt;HTML&lt;/code&gt; module. Then we define a &lt;code&gt;method_missing&lt;/code&gt; class method in this module:&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;HTML&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;HTML&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;method_missing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_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;args&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="s2"&gt;"&amp;lt;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;method_id&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;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;method_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;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;Our method will simply build an HTML tag using the missing &lt;code&gt;method_id&lt;/code&gt; — &lt;code&gt;:div&lt;/code&gt; for a call to &lt;code&gt;HTML.div&lt;/code&gt;, for example.&lt;/p&gt;

&lt;p&gt;Note that class methods are also subject to the Method Lookup Path.&lt;/p&gt;

&lt;p&gt;We could enhance our HTML tag generator by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;using the block argument to handle nested tags&lt;/li&gt;
&lt;li&gt;handling single tags — &lt;code&gt;&amp;lt;br/&amp;gt;&lt;/code&gt; for example&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But note that with a few lines of code, we are able to generate a huge amount of HTML tags.&lt;/p&gt;

&lt;p&gt;So, to recap:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;method_missing&lt;/code&gt; is a good entry point to create DSLs where most of the commands will share a set of identified patterns.&lt;/p&gt;

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

&lt;p&gt;We went all the way up the ancestor chain in Ruby and dove into &lt;code&gt;BasicObject#method_missing&lt;/code&gt;. &lt;code&gt;BasicObject#method_missing&lt;/code&gt; is part of the &lt;em&gt;Ruby Hook Methods&lt;/em&gt;. It is used to interact with objects at some precise moments in their lifecycle. Like any of the other &lt;em&gt;Ruby Hook Methods&lt;/em&gt;, this hook method has to be used carefully. And by carefully, we mean that it should never modify the behaviors of the &lt;em&gt;Ruby Object Model&lt;/em&gt;—except when you are playing around with it or writing a blog post on it ;-)&lt;/p&gt;

&lt;p&gt;Voilà!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Guest author Mehdi Farsi is the founder of &lt;a href="https://www.rubycademy.com"&gt;www.rubycademy.com&lt;/a&gt; which will offer cool courses to learn Ruby and Ruby on Rails when it launches soon.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>learning</category>
    </item>
    <item>
      <title>Object Marshalling in Ruby</title>
      <dc:creator>Mehdi FARSI</dc:creator>
      <pubDate>Fri, 29 Mar 2019 10:06:20 +0000</pubDate>
      <link>https://dev.to/appsignal/object-marshalling-in-ruby-2gck</link>
      <guid>https://dev.to/appsignal/object-marshalling-in-ruby-2gck</guid>
      <description>&lt;p&gt;In this article, we’re going to dive into object marshalling. We'll explain what it is, look at the Marshall module, and then go through an example. We'll then go a step deeper and compare the &lt;code&gt;_dump&lt;/code&gt; and &lt;code&gt;self._load&lt;/code&gt; methods. Let's go!&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Object Marshalling?
&lt;/h2&gt;

&lt;p&gt;When you are writing code, you might want to save an object and transmit it to another program or reuse it in your next program execution. Object marshalling is used in Sidekiq, for example; when a Sidekiq job is enqueued in a Ruby on Rails application, then a serialization of this job — which is nothing more than an object — is inserted in Redis. The Sidekiq process is then able to deserialize this JSON and reconstitute the original job from the JSON.&lt;/p&gt;

&lt;p&gt;In computer programming, this process of serialization and deserialization of an object is what we commonly call &lt;em&gt;object marshalling&lt;/em&gt;. Now, let’s look at what Ruby natively provides to handle Object Marshalling.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Marshal Module
&lt;/h2&gt;

&lt;p&gt;As Ruby is a fully object oriented programming language, it provides a way to serialize and store objects using the &lt;code&gt;Marshall&lt;/code&gt; module in its standard library. It allows you to serialize an object to a byte stream that can be stored and deserialized in another Ruby process.&lt;/p&gt;

&lt;p&gt;So, let’s serialize a string and take a closer look at the serialized object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;hello_world&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'hello world!'&lt;/span&gt;

&lt;span class="n"&gt;serialized_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hello_world&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "\x04\bI\"\x11hello world!\x06:\x06ET"&lt;/span&gt;
&lt;span class="n"&gt;serialized_string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;                       &lt;span class="c1"&gt;# =&amp;gt; String&lt;/span&gt;

&lt;span class="n"&gt;deserialized_hello_world&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serialized_string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "hello world!"&lt;/span&gt;

&lt;span class="n"&gt;hello_world&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object_id&lt;/span&gt;              &lt;span class="c1"&gt;# =&amp;gt; 70204420126020&lt;/span&gt;
&lt;span class="n"&gt;deserialized_hello_world&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object_id&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; 70204419825700&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We then call the &lt;code&gt;Marshal.dump&lt;/code&gt; module method to serialize our string. We store the return value—which contains our serialized string—in the &lt;code&gt;serialized_string&lt;/code&gt; variable. This string can be stored in a file and the file can be reused to reconstitute the original object in another process. We then call the &lt;code&gt;Marshal.load&lt;/code&gt; method to reconstitute the original object from the byte stream.&lt;/p&gt;

&lt;p&gt;We can see that this freshly reconstituted string has a different &lt;code&gt;object_id&lt;/code&gt; than the &lt;code&gt;hello_world&lt;/code&gt; string, which means it's a different object, but it contains the same data.&lt;/p&gt;

&lt;p&gt;Pretty cool! But how is the &lt;code&gt;Marshal&lt;/code&gt; module able to reconstruct the string? And, what if I want to have control over which attributes to serialize and deserialize?&lt;/p&gt;

&lt;h2&gt;
  
  
  A Concrete Example of Object Marshalling
&lt;/h2&gt;

&lt;p&gt;To answer these questions, let’s implement a marshalling strategy on a custom struct named &lt;code&gt;User&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;User&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;:fullname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&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="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Mehdi Farsi'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="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="ss"&gt;:operator&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;User&lt;/code&gt; struct defines 3 attributes: &lt;code&gt;fullname&lt;/code&gt;, &lt;code&gt;age&lt;/code&gt;, and &lt;code&gt;roles&lt;/code&gt;. For this example we have a business rule where we only serialize when it matches the following criteria:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;fullname&lt;/code&gt; contains less than 64 characters&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;roles&lt;/code&gt; array does not contain the &lt;code&gt;:admin&lt;/code&gt; role&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To do so, we can define a &lt;code&gt;User#marshal_dump&lt;/code&gt; method to implement our custom serialization strategy. This method will be called when we invoke the &lt;code&gt;Marshal.dump&lt;/code&gt; method with an instance of &lt;code&gt;User&lt;/code&gt; struct as parameter. Let’s define this method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;User&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;:age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:fullname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:roles&lt;/span&gt;&lt;span class="p"&gt;)&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;marshal_dump&lt;/span&gt;
    &lt;span class="p"&gt;{}.&lt;/span&gt;&lt;span class="nf"&gt;tap&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;result&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:age&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:fullname&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fullname&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;fullname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:roles&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;roles&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt; &lt;span class="ss"&gt;:admin&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Mehdi Farsi'&lt;/span&gt;&lt;span class="p"&gt;,&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="ss"&gt;:operator&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;user_dump&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&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="c1"&gt;# 'in User#marshal_dump'&lt;/span&gt;
&lt;span class="n"&gt;user_dump&lt;/span&gt;                      &lt;span class="c1"&gt;# =&amp;gt; "\x04\bU:\tUser{\a:\bageI\"\x10Mehdi Farsi\x06:\x06ET:\rfullnamei/"&lt;/span&gt;

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



&lt;p&gt;In the above example, we can see that our &lt;code&gt;User#marshal_dump&lt;/code&gt; method is called when we invoke Marshal.dump(user). The &lt;code&gt;user_dump&lt;/code&gt; variable contains the string which is the serialization of our &lt;code&gt;User&lt;/code&gt; instance.&lt;/p&gt;

&lt;p&gt;Now that we have our dump, let’s deserialize it to reconstitute our user. To do so, we define a &lt;code&gt;User#marshal_load&lt;/code&gt; method which is in charge of implementing the deserialization strategy of a &lt;code&gt;User&lt;/code&gt; dump.&lt;/p&gt;

&lt;p&gt;So let’s define this method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;User&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;:age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:fullname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:roles&lt;/span&gt;&lt;span class="p"&gt;)&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;marshal_dump&lt;/span&gt;
    &lt;span class="p"&gt;{}.&lt;/span&gt;&lt;span class="nf"&gt;tap&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;result&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:age&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:fullname&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fullname&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;fullname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:roles&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;roles&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt; &lt;span class="ss"&gt;:admin&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;marshal_load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serialized_user&lt;/span&gt;&lt;span class="p"&gt;)&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;age&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serialized_user&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:age&lt;/span&gt;&lt;span class="p"&gt;]&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;fullname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serialized_user&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:fullname&lt;/span&gt;&lt;span class="p"&gt;]&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;roles&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serialized_user&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:roles&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Mehdi Farsi'&lt;/span&gt;&lt;span class="p"&gt;,&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="ss"&gt;:operator&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;user_dump&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&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="c1"&gt;# 'in User#marshal_dump'&lt;/span&gt;
&lt;span class="n"&gt;user_dump&lt;/span&gt;                      &lt;span class="c1"&gt;# =&amp;gt; "\x04\bU:\tUser{\a:\bagei/:\rfullnameI\"\x10Mehdi Farsi\x06:\x06ET"&lt;/span&gt;

&lt;span class="n"&gt;original_user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_dump&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 'in User#marshal_load'&lt;/span&gt;
&lt;span class="n"&gt;original_user&lt;/span&gt;                            &lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;struct User age=42, fullname="Mehdi Farsi", roles=[]&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the above example, we can see that our &lt;code&gt;User#marshal_load method&lt;/code&gt; is called when we invoke &lt;code&gt;Marshal.load(user_dump)&lt;/code&gt;. The &lt;code&gt;original_user&lt;/code&gt; variable contains a struct which is a reconstitution of our user instance.&lt;/p&gt;

&lt;p&gt;Note that the &lt;code&gt;original_user.roles&lt;/code&gt; is not similar to the &lt;code&gt;user.roles&lt;/code&gt; array since during the serialization, &lt;code&gt;user.roles&lt;/code&gt; included the &lt;code&gt;:admin&lt;/code&gt; role. So the &lt;code&gt;user.roles&lt;/code&gt; wasn’t serialized into the &lt;code&gt;user_dump&lt;/code&gt; variable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The _dump and self._load Methods
&lt;/h2&gt;

&lt;p&gt;When &lt;code&gt;Marshal.dump&lt;/code&gt; and &lt;code&gt;Marshal.load&lt;/code&gt; are invoked, these methods call the &lt;code&gt;marshal_dump&lt;/code&gt; and the &lt;code&gt;marshal_load&lt;/code&gt; methods on the object passed as the parameter of these methods.&lt;/p&gt;

&lt;p&gt;But, what if I tell you that the &lt;code&gt;Marshal.dump&lt;/code&gt; and the &lt;code&gt;Marshal.load&lt;/code&gt; methods try to call two other methods named &lt;code&gt;_dump&lt;/code&gt; and &lt;code&gt;self._load&lt;/code&gt; on the object passed as parameter?&lt;/p&gt;

&lt;h2&gt;
  
  
  The _dump Method
&lt;/h2&gt;

&lt;p&gt;The differences between the &lt;code&gt;marshal_dump&lt;/code&gt; and the &lt;code&gt;_dump&lt;/code&gt; methods are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you need to handle the serialization strategy at a lower level when using the &lt;code&gt;_dump&lt;/code&gt; method — you need to return a string that represents the data to serialize&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;marshal_dump&lt;/code&gt; method takes precedence over &lt;code&gt;_dump&lt;/code&gt; if both are defined&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s have a look to the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;User&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;:age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:fullname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:roles&lt;/span&gt;&lt;span class="p"&gt;)&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;_dump&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fullname&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&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;end&lt;/span&gt;

&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Mehdi Farsi'&lt;/span&gt;&lt;span class="p"&gt;,&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="ss"&gt;:operator&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="no"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&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="c1"&gt;# =&amp;gt; "\x04\bIu:\tUser\x1342:Mehdi Farsi\x06:\x06EF"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;User#_dump&lt;/code&gt; method, we have to instantiate and return the serialization object — the string that represents your serialization.&lt;/p&gt;

&lt;p&gt;In the following example, we define &lt;code&gt;User#marshal_dump&lt;/code&gt; and &lt;code&gt;User#_dump&lt;/code&gt; methods and return a string to see which method is called&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;User&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;:age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:fullname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:roles&lt;/span&gt;&lt;span class="p"&gt;)&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;marshal_dump&lt;/span&gt;
    &lt;span class="s1"&gt;'in User#marshal_dump'&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;_dump&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;
    &lt;span class="s1"&gt;'in User#_dump'&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Mehdi Farsi'&lt;/span&gt;&lt;span class="p"&gt;,&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="ss"&gt;:operator&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;user_dump&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&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="c1"&gt;# "in User#marshal_dump"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can see that only the &lt;code&gt;User#marshal_dump&lt;/code&gt; is called even though they’re both defined. &lt;/p&gt;

&lt;h2&gt;
  
  
  The self._load Method
&lt;/h2&gt;

&lt;p&gt;Now, let's look at the &lt;code&gt;marshal_load&lt;/code&gt; and &lt;code&gt;_load&lt;/code&gt; methods.&lt;/p&gt;

&lt;p&gt;The differences between the &lt;code&gt;marshal_load&lt;/code&gt; and the &lt;code&gt;_load&lt;/code&gt; methods are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to handle the deserialization strategy at a lower level when using the &lt;code&gt;_load&lt;/code&gt; method — You are in charge of instantiating the original object.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;marshal_load&lt;/code&gt; method takes a deserialized object as an argument when the &lt;code&gt;_self.load&lt;/code&gt; method takes the serialized string as an argument.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;marshal_load&lt;/code&gt; method is an instance method when the &lt;code&gt;self._load&lt;/code&gt; is a class method.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s take a look at the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;User&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;:age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:fullname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:roles&lt;/span&gt;&lt;span class="p"&gt;)&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;_dump&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fullname&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&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="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_load&lt;/span&gt; &lt;span class="n"&gt;serialized_user&lt;/span&gt;
    &lt;span class="n"&gt;user_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serialized_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;':'&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;user_info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Array&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="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Mehdi Farsi'&lt;/span&gt;&lt;span class="p"&gt;,&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="ss"&gt;:operator&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;user_dump&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&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="n"&gt;user_dump&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "\x04\bIu:\tUser\x1342:Mehdi Farsi\x06:\x06EF"&lt;/span&gt;

&lt;span class="n"&gt;original_user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_dump&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;original_user&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;struct User age="Mehdi Farsi", fullname=42, roles=[]&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;User._load&lt;/code&gt; method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we deserialize the string returned by the &lt;code&gt;User#_dump&lt;/code&gt; method&lt;/li&gt;
&lt;li&gt;we instantiate a new &lt;code&gt;User&lt;/code&gt; by passing the deserialized information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can see that we are in charge of allocating and instantiating the object used to reconstitute our original user.&lt;/p&gt;

&lt;p&gt;So the &lt;code&gt;Marshal.load&lt;/code&gt; coupled to &lt;code&gt;marshal_load&lt;/code&gt; takes care of instantiating the reconstituted original object. Then it calls the &lt;code&gt;marshal_load&lt;/code&gt; method with the serialized object passed as argument on the freshly instantiated object.&lt;/p&gt;

&lt;p&gt;On the contrary, a call to &lt;code&gt;Marshal.load&lt;/code&gt; coupled to &lt;code&gt;_load&lt;/code&gt; lets the &lt;code&gt;self._load&lt;/code&gt; class method be in charge of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;deserializing the data returned by the &lt;code&gt;_dump&lt;/code&gt; method&lt;/li&gt;
&lt;li&gt;instantiating the reconstituted original object&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Depending on your needs, you can decide to implement a higher or lower serialization/deserialization strategy. To do so, you can use the Marshal module coupled to the appropriate Marshal hook methods.&lt;/p&gt;

&lt;p&gt;Voilà!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Guest author Mehdi Farsi is the founder of &lt;a href="https://www.rubycademy.com"&gt;www.rubycademy.com&lt;/a&gt; which will offer cool courses to learn Ruby and Ruby on Rails when it launches soon.&lt;/em&gt;&lt;/p&gt;

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