<?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>Forem: Juanito Fatas</title>
    <description>The latest articles on Forem by Juanito Fatas (@juanitofatas).</description>
    <link>https://forem.com/juanitofatas</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%2F41858%2Fc3de30c9-7445-4c92-92a1-8e909404bc2c.jpeg</url>
      <title>Forem: Juanito Fatas</title>
      <link>https://forem.com/juanitofatas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/juanitofatas"/>
    <language>en</language>
    <item>
      <title>Optimization Techniques by Benchmark Winners</title>
      <dc:creator>Juanito Fatas</dc:creator>
      <pubDate>Wed, 26 Feb 2020 02:44:55 +0000</pubDate>
      <link>https://forem.com/juanitofatas/optimization-techniques-by-benchmark-winners-nof</link>
      <guid>https://forem.com/juanitofatas/optimization-techniques-by-benchmark-winners-nof</guid>
      <description>&lt;p&gt;This post is based on &lt;a href="https://twitter.com/jeremyevans0"&gt;Jeremy Evans&lt;/a&gt;‘s Optimization Techniques Used by the Benchmark Winners presentation. &lt;a href="https://code.jeremyevans.net/presentations/rubykaigi2019/"&gt;Slides&lt;/a&gt; | &lt;a href="https://www.youtube.com/watch?v=RuGZCcEL2F8"&gt;YouTube&lt;/a&gt; at Ruby Kaigi 2019. It‘s better to watch his fabulous presentation, but you can come back here for written references. These techniques coming from maintaining &lt;a href="https://github.com/jeremyevans/sequel"&gt;Sequel&lt;/a&gt; and &lt;a href="https://github.com/jeremyevans/roda"&gt;Roda&lt;/a&gt;. These two gems have always been 0 issues. It‘s probably the best maintained gems. Sequel and Roda are the leaders for Ruby in &lt;a href="https://www.techempower.com/benchmarks/"&gt;TechEmpower&lt;/a&gt; benchmark results. Let‘s see what lessons can we learn to optimize Ruby.&lt;/p&gt;

&lt;p&gt;These techniques may not be the best to write at application code level but good when building libraries, optimize critical path of your application. The ideas and principles are universally applicable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Avoid processing
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://youtu.be/RuGZCcEL2F8?t=144"&gt;2:24&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;No code is faster than no code&lt;br&gt;
-- Merb Motto&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fastest code does the least. Execute less code. Run code once instead of many times, once is better than many. In big-o terms: &lt;code&gt;O(1) &amp;gt; O(n)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Take initialize model instance as example, the Sequel is definitely faster than Active Record because it does much less things.&lt;/p&gt;

&lt;p&gt;Active Record:&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;# https://github.com/rails/rails/blob/8ae8e19a33f4749e529b1649f4f0ace1dbb37285/activerecord/lib/active_record/core.rb#L357-L369&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;init_with_attributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# :nodoc:&lt;/span&gt;
  &lt;span class="vi"&gt;@new_record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_record&lt;/span&gt;
  &lt;span class="vi"&gt;@attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;

  &lt;span class="n"&gt;init_internals&lt;/span&gt;

  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;block_given?&lt;/span&gt;

  &lt;span class="n"&gt;_run_find_callbacks&lt;/span&gt;
  &lt;span class="n"&gt;_run_initialize_callbacks&lt;/span&gt;

  &lt;span class="nb"&gt;self&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sequel:&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;# https://github.com/jeremyevans/sequel/blob/4a146796f273ce14e121954ad4e7f3134209386d/lib/sequel/model/base.rb#L221&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;allocate&lt;/span&gt;
  &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_variable_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:@values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;o&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Delay Computations
&lt;/h2&gt;

&lt;p&gt;For web app, it means to do at initialization time is better than doing at Runtime. See Hound applies this for putting &lt;a href="https://github.com/houndci/hound/blob/f308b0cb3ef328a533043e144042f5c29044add5/config/initializers/constants.rb"&gt;environment variables into constants&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Active Record &amp;amp; Sequel Callbacks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Active Record runs find and initialize callbacks during initialization. Even when there are no callbacks defined on the model, so it slows down:&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;# lib/active_record/core.rb&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;init_with_attributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="n"&gt;_run_find_callbacks&lt;/span&gt;
  &lt;span class="n"&gt;_run_initialize_callbacks&lt;/span&gt;

  &lt;span class="o"&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;Sequel does this by having a &lt;a href="http://sequel.jeremyevans.net/plugins.html"&gt;Plugin System&lt;/a&gt;&lt;sup id="fnref1"&gt;1&lt;/sup&gt;. In Sequel, if you need callbacks, add &lt;code&gt;plugin :after_initialize&lt;/code&gt; to your model. Nothing gets run if you‘re not using callbacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inheritance gives every subclass things that they may not need.&lt;/strong&gt; Prefer Composition over Inheritance. Plugins give all subclass a chance to only take what they need. Sequel and Roda use plugins for most features so they are faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reduce Object Allocations
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://youtu.be/RuGZCcEL2F8?t=628"&gt;10:28&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;init_internals&lt;/code&gt; in Active Record set few instance variables to &lt;code&gt;nil&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;init_internals&lt;/span&gt;
  &lt;span class="vi"&gt;@primary_key&lt;/span&gt;              &lt;span class="o"&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;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;primary_key&lt;/span&gt;
  &lt;span class="vi"&gt;@readonly&lt;/span&gt;                 &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="vi"&gt;@destroyed&lt;/span&gt;                &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="vi"&gt;@marked_for_destruction&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="vi"&gt;@destroyed_by_association&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
  &lt;span class="vi"&gt;@_start_transaction_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
  &lt;span class="vi"&gt;@transaction_state&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&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;define_attribute_methods&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jeremy found &lt;a href="https://youtu.be/RuGZCcEL2F8?t=267"&gt;avoid &lt;code&gt;@instance_variable = nil&lt;/code&gt; resulted in 150% faster&lt;/a&gt; in Sequel and Roda. This is controversial because only in verbose mode, using instance variable without define first will emit warnings. Emit warnings makes it slower. He made a patch to remove such warnings but got rejected for backward compatibility.&lt;/p&gt;

&lt;p&gt;You can find another example of delay allocation of instance variables in &lt;a href="https://github.com/rails/rails/commit/b1458218c95d85c4ce911dd3e99da5ae7cf7aeee"&gt;this commit from rails/rails&lt;/a&gt;. Delay setting instance variable to hash by setting it to &lt;code&gt;nil&lt;/code&gt; first.&lt;/p&gt;

&lt;p&gt;Another common place to reduce object allocations is string. Before Ruby 2.3, we need to call &lt;code&gt;freeze&lt;/code&gt; on strings. Since 2.3, we can add a frozen string literal in a file and by default all strings in that file are frozen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reduce String Allocations
&lt;/h3&gt;

&lt;p&gt;Before frozen string literal (Ruby &amp;lt; 2.3), introduce a constant for common places of strings &lt;code&gt;SELECT = 'SELECT'.freeze&lt;/code&gt; was okay:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SELECT'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;
&lt;span class="no"&gt;SPACE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;
&lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'FROM'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;select_sql&lt;/span&gt;
  &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;String&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;sql&lt;/span&gt; &lt;span class="err"&gt;‌&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;SELECT&lt;/span&gt; &lt;span class="err"&gt;‌&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;SPACE&lt;/span&gt;
  &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="err"&gt;‌&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;literal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="err"&gt;‌&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;SPACE&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;‌&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;‌&lt;/span&gt; &lt;span class="no"&gt;SPACE&lt;/span&gt;
  &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="err"&gt;‌&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;literal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table&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;Since Ruby 2.3:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;select_sql&lt;/span&gt;
  &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;String&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;sql&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"SELECT "&lt;/span&gt;
  &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;literal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;" FROM "&lt;/span&gt;
  &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;literal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table&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;It‘s simpler and easier to understand. Avoids string allocations in the meantime with less operations (&lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;), hence faster.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reduce Hash allocations
&lt;/h3&gt;

&lt;p&gt;Avoid default hash in method definition:&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;Sequel::Dataset&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;union&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="n"&gt;compound_clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:union&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Introduce an empty frozen hash constant:&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;Sequel::Dataset&lt;/span&gt;
  &lt;span class="nc"&gt;OPTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;

  &lt;span class="c1"&gt;# 100% faster than `opts={}`.&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;union&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="no"&gt;OPTS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;compound_clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:union&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# Keyword argument is slower than Optimal hash constant.&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;union&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;compound_clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:union&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Right now double splat keyword arguments are slower (2.7) than above empty frozen hash constant technique. Keyword arguments also have maintenance barriers the method caller and callee all need to change when keyword changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reduce Proc Allocation
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://youtu.be/RuGZCcEL2F8?t=903"&gt;15:03&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For proc does not depend on something else or any runtime state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;indifferent_params&lt;/span&gt;
  &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&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;k&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_a?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can extract into a constant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;IND&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;proc&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&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;k&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_a?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;indifferent_params2&lt;/span&gt;
  &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;IND&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;About 300%+ faster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ips&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;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"inline proc"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;indifferent_params&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"constant proc"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;indifferent_params2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compare!&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Comparison&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
       &lt;span class="n"&gt;constant&lt;/span&gt; &lt;span class="ss"&gt;proc:  &lt;/span&gt;&lt;span class="mf"&gt;5645873.6&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
         &lt;span class="n"&gt;inline&lt;/span&gt; &lt;span class="ss"&gt;proc:  &lt;/span&gt;&lt;span class="mf"&gt;1469374.7&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;3.84&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;  &lt;span class="n"&gt;slower&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reduce Array Allocation
&lt;/h3&gt;

&lt;p&gt;This is not from the presentation but I think it‘s great to also include an example here.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;transform_values&lt;/code&gt; when modifying hashes. See &lt;a href="https://github.com/rails/rails/commit/df81f2e5f5df46c9c1db27530bbd301b6e23c4a7"&gt;this commit&lt;/a&gt; from rails/rails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;    def escape(params)
&lt;span class="gd"&gt;-     Hash[params.map { |k, v| [k, Rack::Utils.escape(v)] }]
&lt;/span&gt;&lt;span class="gi"&gt;+     params.transform_values { |v| Rack::Utils.escape(v) }
&lt;/span&gt;    end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Minimize Indirection
&lt;/h2&gt;

&lt;p&gt;Say a common operation in our app is to convert a string into Integer. We could have a &lt;code&gt;lambda&lt;/code&gt;, a kernel method, a dedicated object with &lt;code&gt;call&lt;/code&gt; to do so, or an object that aliased &lt;code&gt;call&lt;/code&gt; to &lt;code&gt;Integer()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"42"&lt;/span&gt;

&lt;span class="n"&gt;using_lambda&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;using_kernel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Kernel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:Integer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;using_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&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;def&lt;/span&gt; &lt;span class="nc"&gt;using_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="no"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;no_indirection_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&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;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;no_indirection_object&lt;/span&gt;
  &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="no"&gt;Integer&lt;/span&gt;
  &lt;span class="kp"&gt;public&lt;/span&gt; &lt;span class="ss"&gt;:call&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ips&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;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"lambda"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;using_lambda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Kernel"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;using_kernel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Object"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;using_object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Object v2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;no_indirection_object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compare!&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Comparison:
  Object v2:  6258404.2 i/s
  Object:     5674514.7 i/s - same-ish: difference falls within error
  lambda:     5199998.6 i/s - 1.20x  slower
  Kernel:     5130274.6 i/s - 1.22x  slower
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We see using &lt;code&gt;Kernel.method&lt;/code&gt; is slowest here. A lambda is slightly faster than that. Define a method on an object is faster than calling a lambda. Avoid indirection (by alias &lt;code&gt;call&lt;/code&gt; to &lt;code&gt;Integer&lt;/code&gt;) further makes it &lt;code&gt;~10%&lt;/code&gt; faster. The benchmark example above aligns with Jeremy‘s observations on benchmarking Sequel from the presentation. A &lt;a href="https://gist.github.com/rmosolgo/6c6a7d787e0f1666f4c6d858c8402a01#gistcomment-1843329"&gt;similar observation&lt;/a&gt; is also found from graphql-ruby land that they‘re now in favor of &lt;a href="https://rmosolgo.github.io/blog/2018/03/25/why-a-new-schema-definition-api/"&gt;method call instead of using procs&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining Methods
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://youtu.be/RuGZCcEL2F8?t=1142"&gt;19:02&lt;/a&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;def&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# 50% slower than `def foo; 1; end`&lt;/span&gt;
&lt;span class="n"&gt;define_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we always want to define method with &lt;code&gt;def&lt;/code&gt;. Sometimes we want to define at runtime. Take Sequel as example, it needs to dynamically define model columns‘s setters and getters, can achieve with &lt;code&gt;class_eval&lt;/code&gt; + &lt;code&gt;def&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# def_column&lt;/span&gt;
&lt;span class="n"&gt;columns&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;column&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;class_eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"def &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; @values[:&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]; end"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;class_eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"def &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;=(v); @values[:&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;] = v; end"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works for column name without spaces &lt;code&gt;"name"&lt;/code&gt;, with space &lt;code&gt;"employee name"&lt;/code&gt; it does not work. We need to use &lt;code&gt;define_method&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;columns&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;column&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;column&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_sym&lt;/span&gt;
  &lt;span class="n"&gt;define_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="vi"&gt;@values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;define_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="ss"&gt;="&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="vi"&gt;@values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;v&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;which is slower than using &lt;code&gt;class_eval + def&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These columns with "bad" names are not the majority of the case but changing the implementation to this hurts performance. Here comes another general optimization principle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate Common from Uncommon
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://youtu.be/RuGZCcEL2F8?t=1278"&gt;21:18&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We usually have a fast approach for the simple cases but it fails in more complex cases. Assume the simple cases are more common, we can speed up by separating the two cases. Sequel separates the common from the uncommon, to have the best of both worlds. Below are simplified from Sequel‘s &lt;a href="https://github.com/jeremyevans/sequel/blob/cc5c1612fb4c42e7cbf6db6b0572001fd5bf6b58/lib/sequel/model/base.rb#L778-L788"&gt;column definitions&lt;/a&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;def&lt;/span&gt; &lt;span class="nf"&gt;def_column_accessor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bad_columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;partition&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="sr"&gt;/\A[A-Za-z_][A-Za-z0-9_]*\z/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;bad_columns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;def_bad_column_accessor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt; &lt;span class="c1"&gt;# define_method&lt;/span&gt;
  &lt;span class="n"&gt;columns&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;column&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="c1"&gt;# faster with `def`&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;In general &lt;code&gt;def&lt;/code&gt; &amp;gt; &lt;code&gt;define_method&lt;/code&gt;, but there is one case where &lt;code&gt;define_method&lt;/code&gt; is preferred for performance. Let‘s see an example:&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;Def&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;def_numbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;class_eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"def numbers; (&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="si"&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;last&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;).to_a.freeze; end"&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;def_numbers2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;
    &lt;span class="n"&gt;define_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:numbers2&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;array&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ips&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;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"def"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Def&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;def_numbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"define_method"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Def&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;def_numbers2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compare!&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Comparison&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
       &lt;span class="ss"&gt;define_method:   &lt;/span&gt;&lt;span class="mf"&gt;542551.0&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
                 &lt;span class="ss"&gt;def:    &lt;/span&gt;&lt;span class="mf"&gt;62085.7&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;8.74&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;  &lt;span class="n"&gt;slower&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So prefer &lt;code&gt;def&lt;/code&gt; over &lt;code&gt;define_method&lt;/code&gt; unless you can access local variables from surrounding scope to avoid computations, only then &lt;code&gt;define_method&lt;/code&gt; &amp;gt; &lt;code&gt;def&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Related to this. If we need to accept blocks and store blocks, and use &lt;code&gt;instance_exec&lt;/code&gt; to execute these blocks. Let‘s implement a before hook to demonstrate this idea.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;before_hooks&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;block&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;before&lt;/span&gt;
  &lt;span class="c1"&gt;# execute all blocks passed to self.before&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;before_hooks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;instance_exec&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="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works but &lt;code&gt;instance_exec&lt;/code&gt; creates singelton class for the instance, it‘s faster to use methods. We can define before hooks methods by naming them based on their position in the array, then we pass to &lt;code&gt;define_method&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="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;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;meth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:"_before_hook_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;before_hooks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="ss"&gt;"&lt;/span&gt;
  &lt;span class="n"&gt;define_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;meth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;before_hooks&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;meth&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;before&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;before_hooks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute these before hooks could be a &lt;code&gt;send&lt;/code&gt; which is faster. This is good but we can do better. Since we know which methods will be executed, we can define the &lt;code&gt;before&lt;/code&gt; to execute these before hook methods by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;before&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="c1"&gt;# ...&lt;/span&gt;

  &lt;span class="nb"&gt;class_eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"def before; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;before_hooks&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="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; end"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is faster because it avoids the need to call each on before hooks array and each method invoked directly instead of one indirection &lt;code&gt;send&lt;/code&gt;. But we can still do better.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;before&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="c1"&gt;# ...&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;before_hooks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="nb"&gt;class_eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"def before; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;before_hooks&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="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; end"&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;class_eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"alias before &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;before_hooks&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;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If there is only a single before hook, we can alias to that method hence minimized indirection.&lt;/p&gt;

&lt;p&gt;This approach to implementing before hooks compare to using &lt;code&gt;define_method&lt;/code&gt;, is about 200% faster because it avoids a lot of internal indirections. One caveat of this approach is that it does not work with &lt;code&gt;before { |x| }&lt;/code&gt;. But we can fix this by:&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;unless&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arity&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arity&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;
  &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;instance_exec&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;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Optimize Inner Loops
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://youtu.be/RuGZCcEL2F8?t=1576"&gt;26:16&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another best place to start optimizing is inside any inner loops. Let‘s see an example from Sequel‘s Anywhere adapter:&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;# https://github.com/jeremyevans/sequel/blob/ae50b5e98efb3ad902fb37f370cbf237644a12d3/lib/sequel/adapters/sqlanywhere.rb#L157-L187&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_fetch_next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="n"&gt;max_cols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_num_cols&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;h2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="n"&gt;max_cols&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&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;cols&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;col_map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_get_column_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_get_column_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="n"&gt;cps&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_get_column_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]].&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;
          &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_get_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_get_column_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;
              &lt;span class="n"&gt;cps&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_get_column_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]].&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_get_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;convert&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;cps&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_get_column_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]].&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_get_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
                  &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_get_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;h2&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there are some hidden ternary operators without parentheses...So this is complex, but not the reason why it‘s slow. It‘s slow because:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;db.api.sqlany_get_column_info(rs, cols)&lt;/code&gt; repeated 5 times with same arguments in the inner loop. Another one is &lt;code&gt;db.api.sqlany_get_column(rs, cols)[1]&lt;/code&gt; repeated 4 times. After a serious refactoring, now we arrive at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_rows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@db&lt;/span&gt;
  &lt;span class="n"&gt;cps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;conversion_procs&lt;/span&gt;
  &lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;
  &lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;convert&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;convert_smallint_to_bool&lt;/span&gt;
    &lt;span class="n"&gt;col_infos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_num_cols&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;times&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;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&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="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_get_column_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;cp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
        &lt;span class="n"&gt;cps&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;500&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;convert&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;cps&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="n"&gt;col_infos&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;output_identifier&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="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;end&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;columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;col_infos&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:first&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;col_infos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt;
      &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_fetch_next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;
          &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;col_infos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
          &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_get_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
          &lt;span class="n"&gt;h&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cp&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;h&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="nb"&gt;self&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The inner loop now becomes much simpler:&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;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;
  &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;col_infos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_get_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;h&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cp&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All operations inside are stored on local variables. This seems not a big deal but if you are retrieving 100,000 rows with each row of 10 columns, this makes a big difference. By define local variables, this saves millions of method calls. This is another general optimization principle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prefer Local Variables
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://youtu.be/RuGZCcEL2F8?t=1742"&gt;29:02&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Prefer local variables whenever possible especially in inner loop as demostrated above.&lt;/p&gt;

&lt;p&gt;Local variables &amp;gt; Instance variables&lt;br&gt;
&lt;a href="https://github.com/rails/rails/commit/58df9a452fa75f10365849775292dcf0ae79a6f2"&gt;Local variables &amp;gt; Constant&lt;/a&gt;&lt;br&gt;
Local variables &amp;gt; Method Calls&lt;/p&gt;

&lt;p&gt;local variables are faster because it minimize the number of indirections.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;while v.s. each&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let‘s go back to the above refactoring example. The deliberate use of &lt;code&gt;while&lt;/code&gt; in the inner loop:&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;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;
  &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;col_infos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqlany_get_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;h&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cp&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inner loop like this is one of the few places that make sense to use &lt;code&gt;while&lt;/code&gt; instead of &lt;code&gt;each&lt;/code&gt; because using &lt;code&gt;each&lt;/code&gt; for inner loops can hurt performance, because it requires a seperate a stackframe to push and pop for each iteration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose Faster Algorithms
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://youtu.be/RuGZCcEL2F8?t=1867"&gt;31:07&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sinatra routes (by pattern) v.s. &lt;a href="https://www.youtube.com/watch?v=W8zglFFFRMM"&gt;Roda‘s routing tree&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Given thousands of routes. Sinatra will be busy matching against all routes. &lt;code&gt;O(N)&lt;/code&gt; Roda‘s routing tree would take route segments. Filter out the segment to the right tree. &lt;code&gt;O(log(N))&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Roda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;route&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;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt; &lt;span class="s2"&gt;"foo"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c1"&gt;# /foo ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt; &lt;span class="s2"&gt;"bar"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c1"&gt;# /bar ...&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;But the worst case is still &lt;code&gt;O(N)&lt;/code&gt; and Jeremy does not accept the worst case being &lt;code&gt;O(n)&lt;/code&gt;... Here comes multi route:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Roda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plugin&lt;/span&gt; &lt;span class="ss"&gt;:multi_route&lt;/span&gt;

&lt;span class="no"&gt;Roda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="c1"&gt;# /foo... }&lt;/span&gt;
&lt;span class="no"&gt;Roda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"bar"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="c1"&gt;# /bar... }&lt;/span&gt;

&lt;span class="no"&gt;Roda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;route&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;multi_route&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Multi route builds a regexp to match initialial segment (&lt;code&gt;/foo&lt;/code&gt;, &lt;code&gt;/bar&lt;/code&gt;, ...) then dispatch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Roda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;route&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;multi_route&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which brings the performance back to &lt;code&gt;O(log(n))&lt;/code&gt;. But he wants &lt;code&gt;O(1)&lt;/code&gt;...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Roda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plugin&lt;/span&gt; &lt;span class="ss"&gt;:static_routing&lt;/span&gt;

&lt;span class="no"&gt;Roda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;static_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="c1"&gt;# /foo... }&lt;/span&gt;
&lt;span class="no"&gt;Roda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;static_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"bar"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="c1"&gt;# /bar... }&lt;/span&gt;

&lt;span class="no"&gt;Roda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;route&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But &lt;code&gt;O(1)&lt;/code&gt; gives up many advantages. In the end, he created &lt;code&gt;hash_routes&lt;/code&gt; plugin to have the best of both worlds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Roda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plugin&lt;/span&gt; &lt;span class="ss"&gt;:hash_routes&lt;/span&gt;

&lt;span class="no"&gt;Roda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash_routes&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash_routes&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"foo/bar"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;

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

&lt;span class="no"&gt;Roda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;route&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;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash_routes&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cache when Possible
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://youtu.be/RuGZCcEL2F8?t=2380"&gt;39:40&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Introduce cache is the highest ratio of the following formula:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  % Increase in Performance
-----------------------------
    Lines of Code Changed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maximum performance increase over minimum lines of code changed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case: Sequel Symbol Literalization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/RuGZCcEL2F8"&gt;40:00&lt;/a&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="ss"&gt;:column_name&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; '"column_name"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="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;split_symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;
  &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="sr"&gt;/\A((?:(?!__).)+)__((?:(?!___).)+)___(.+)\z/&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="vg"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vg"&gt;$2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vg"&gt;$3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;
  &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="sr"&gt;/\A((?:(?!___).)+)___(.+)\z/&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vg"&gt;$2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;
  &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="sr"&gt;/\A((?:(?!__).)+)__(.+)\z/&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="vg"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vg"&gt;$2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;v&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Introduce symbol cache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;SPLIT_SYMBOL_CACHE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;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;split_symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Sequel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;synchronize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;SPLIT_SYMBOL_CACHE&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="sr"&gt;/\A((?:(?!__).)+)__((?:(?!___).)+)___(.+)\z/&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="vg"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vg"&gt;$2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vg"&gt;$3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="sr"&gt;/\A((?:(?!___).)+)___(.+)\z/&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vg"&gt;$2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="sr"&gt;/\A((?:(?!__).)+)__(.+)\z/&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="vg"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vg"&gt;$2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="no"&gt;Sequel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;synchronize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;SPLIT_SYMBOL_CACHE&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;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;v&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;v&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is over 1000% faster after introduced this cache.&lt;/p&gt;

&lt;h3&gt;
  
  
  Globally Frozen, Locally Mutable
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://youtu.be/RuGZCcEL2F8?t=2510"&gt;41:50&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Freeze global state like classes, objects that is accessed by multiple threads. Local objects instantiated per request remain mutable for ease of use (cache). This approach is mainly to improve reliability (thread safe). This also improves performance because frozen object means it is easy to cache them.&lt;/p&gt;

&lt;p&gt;Note that Frozen is not the same as Immutable. Frozen means Immutable State + Mutable Cache.&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;# https://github.com/jeremyevans/sequel/blob/cc5c1612fb4c42e7cbf6db6b0572001fd5bf6b58/lib/sequel/dataset/misc.rb#L25-L30&lt;/span&gt;
&lt;span class="no"&gt;OPTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="vi"&gt;@db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;
  &lt;span class="vi"&gt;@opts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;OPTS&lt;/span&gt; &lt;span class="c1"&gt;# state in frozen hash&lt;/span&gt;
  &lt;span class="n"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;-- mutable cache&lt;/span&gt;
  &lt;span class="nb"&gt;freeze&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;-- freeze this object&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure access to mutable cache is protected by Mutex for thread safety.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimization Through Metaprogramming
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://youtu.be/RuGZCcEL2F8?t=2771"&gt;46:11&lt;/a&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;Album&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Sequel&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Model&lt;/span&gt;
  &lt;span class="n"&gt;dataset_module&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;by_name&lt;/span&gt;
      &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;released&lt;/span&gt;
      &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;released: &lt;/span&gt;&lt;span class="kp"&gt;true&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="c1"&gt;# Album.where(released: true).order(:name).first&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; Album.released.by_name.first&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is good to DRY up code but does not improve performance. Jeremy introduced metaprogramming for users to define like following and speed up by introduced dataset cache to these metaprogramming generated methods:&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;Album&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Sequel&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Model&lt;/span&gt;
  &lt;span class="n"&gt;dataset_module&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="ss"&gt;:by_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="c1"&gt;# def by_name&lt;/span&gt;
                          &lt;span class="c1"&gt;#   cache { order(:name) }&lt;/span&gt;
                          &lt;span class="c1"&gt;# end&lt;/span&gt;

    &lt;span class="n"&gt;where&lt;/span&gt; &lt;span class="ss"&gt;:released&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;released: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="c1"&gt;# def released&lt;/span&gt;
    &lt;span class="c1"&gt;#   cache { where(released: true) }&lt;/span&gt;
    &lt;span class="c1"&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;&lt;strong&gt;Example: Roda String Matching&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/RuGZCcEL2F8?t=2921"&gt;48:41&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Roda was forked from Cuba. The matching of routing segment was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;match_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;consume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Regexp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# https://github.com/soveran/cuba/blob/1dce54d0926c5d6e5daab033a8e9685c6faa4227/lib/cuba.rb#L214-L226&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;consume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;matchdata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PATH_INFO&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\A\/(&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;)(\/|\z)/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;matchdata&lt;/span&gt;

  &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;vars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;matchdata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;captures&lt;/span&gt;

  &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SCRIPT_NAME&lt;/span&gt;&lt;span class="p"&gt;]&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;path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PATH_INFO&lt;/span&gt;&lt;span class="p"&gt;]&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;vars&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="si"&gt;}#{&lt;/span&gt;&lt;span class="n"&gt;matchdata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post_match&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  &lt;span class="n"&gt;captures&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;vars&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="ss"&gt;:consume&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code looks perfectly fine. But let‘s see how Jeremy optimized it. First is to avoid allocations. The first change was to include the proceeding slash in the first capture to avoid extra array allocation for the captures:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- /\A\/(#{pattern})(\/|\z)/
&lt;/span&gt;&lt;span class="gi"&gt;+ /\A(\/(#{pattern}))(\/|\z)/
&lt;/span&gt;
...

- path, *vars = matchdata.captures
&lt;span class="gi"&gt;+ vars = matchdata.captures
&lt;/span&gt;
- env[Rack::SCRIPT_NAME] += "/#{path}"
&lt;span class="gi"&gt;+ env[Rack::SCRIPT_NAME] += vars.shift
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next is to use a regular expression feature, positive lookahead assertion instead of a capture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- /\A(\/(#{pattern}))(\/|\z)/
&lt;/span&gt;&lt;span class="gi"&gt;+ /\A(\/(#{pattern}))(?=\/|\z)/
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we no longer need to pop the last element of capture variables (&lt;code&gt;vars&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- env[Rack::PATH_INFO] = "#{vars.pop}#{matchdata.post_match}"
&lt;/span&gt;&lt;span class="gi"&gt;+ env[Rack::PATH_INFO] = matchdata.post_match
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also avoid the allocation of additional string by using post match directly.&lt;/p&gt;

&lt;p&gt;He then profile and found generating a new regular expression every time &lt;code&gt;consume&lt;/code&gt; was called takes a large portion of time. Then he introduced cached matcher:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;   def match_string(str)
&lt;span class="gd"&gt;-    consume(Regexp.escape(str))
&lt;/span&gt;&lt;span class="gi"&gt;+    consume(self.class.cached_matcher(str) { Regexp.escape(str) })
&lt;/span&gt;   end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This change is possible because &lt;code&gt;consume&lt;/code&gt; was a private method. Another optimizations technique is to keep most methods private.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep Most Methods Private
&lt;/h2&gt;

&lt;p&gt;Only makes a method public if it needs to be public. When method is private, you are free to change its API to improve performance. Public methods have limit options to optimize.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prefer String operations over Regexp operations
&lt;/h3&gt;

&lt;p&gt;In Roda 3.0, the matching of string segment changed to use string operations instead of regular expression matching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;match_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;rp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@remaining_path&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start_with?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;str&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="c1"&gt;# &amp;lt;----&lt;/span&gt;
    &lt;span class="n"&gt;last&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;----&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;
      &lt;span class="vi"&gt;@remaining_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;----&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
      &lt;span class="vi"&gt;@remaining_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But still, there are two String allocations: &lt;code&gt;rp.start_with?("/#{str}")&lt;/code&gt; and &lt;code&gt;rp[last]&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prefer Integer operations over String operations
&lt;/h3&gt;

&lt;p&gt;Iterating by index and checking if first character of string is 47 (&lt;code&gt;47&lt;/code&gt; is ascii code of &lt;code&gt;/&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_match_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;rp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@remaining_path&lt;/span&gt;
  &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;

  &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;rp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rindex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;------&lt;/span&gt;
  &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
  &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;rp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getbyte&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="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;47&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;--- start_with?("/")&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;rp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getbyte&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="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;47&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;--- start_with?("/")&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;
    &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;rp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getbyte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;47&lt;/span&gt;
      &lt;span class="vi"&gt;@remaining_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100000000&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
      &lt;span class="vi"&gt;@remaining_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The most common failure case &lt;code&gt;when nil&lt;/code&gt; also moved up because it happens more often. Another trick is to use a large number that is larger than any reasonable path length: &lt;code&gt;rp[length, 100000000]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Remember that optimizations come last.&lt;br&gt;
First make it work, then make it correct.&lt;br&gt;
After you make it fun, then you can make it fast.&lt;br&gt;
—Jeremy Evans&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://github.com/JuanitoFatas/ruby-performance-tools#profiling"&gt;Profile&lt;/a&gt; to find where to optimize. Then &lt;a href="https://github.com/JuanitoFatas/ruby-performance-tools#benchmark"&gt;Benchmark&lt;/a&gt; your change.&lt;/p&gt;

&lt;p&gt;That‘s all from Jeremy‘s presentation.&lt;/p&gt;




&lt;p&gt;There is no silver bullet. It depends on the context. We must try ourselves. Verify it‘s faster than the other instead of directly quoting anything here.&lt;/p&gt;

&lt;p&gt;The faults are probably mine. I‘m happy to fix if you would &lt;a href="https://twitter.com/JuanitoFatas"&gt;let me know&lt;/a&gt;. You can reach out to him on twitter for more questions: &lt;a href="https://twitter.com/jeremyevans0"&gt;@jeremyevans0&lt;/a&gt; or &lt;a href="https://github.com/jeremyevans"&gt;GitHub&lt;/a&gt; to see more of his work.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://juanitofatas.com/optimization_techniques_by_benchmark_winners"&gt;juanitofatas.com&lt;/a&gt; on January 27th, 2020.&lt;/em&gt;&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Learn more about &lt;a href="https://twin.github.io/the-plugin-system-of-sequel-and-roda/"&gt;the plugin system of Sequel and Roda&lt;/a&gt; from &lt;a href="https://twin.github.io/"&gt;Janko Marohnić&lt;/a&gt;. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>ruby</category>
      <category>optimization</category>
      <category>benchmark</category>
    </item>
    <item>
      <title>Building a Mocking Library in Ruby</title>
      <dc:creator>Juanito Fatas</dc:creator>
      <pubDate>Mon, 27 Jan 2020 09:35:03 +0000</pubDate>
      <link>https://forem.com/juanitofatas/building-a-mocking-library-in-ruby-590a</link>
      <guid>https://forem.com/juanitofatas/building-a-mocking-library-in-ruby-590a</guid>
      <description>&lt;p&gt;This tutorial is based on &lt;a href="http://andylindeman.com"&gt;Andy Lindeman&lt;/a&gt;’s awesome talk — &lt;a href="https://www.youtube.com/watch?v=2aYdtS7FZJA"&gt;Building a Mocking Library&lt;/a&gt; presented at &lt;a href="http://confreaks.tv/events/acr2013"&gt;Ancient City Ruby 2013&lt;/a&gt;. This is not a direct transcript of the video, but the code presented is almost the same (with minimal changes).&lt;/p&gt;

&lt;p&gt;In his talk, Andy showed us how we can build a Mocking library for Minitest with just basic knowledge of Ruby and I felt that it‘s actually a great way to learn Ruby! So I decided to document the talk in writing and share it up here on the blog so that we can all learn together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Goal
&lt;/h2&gt;

&lt;p&gt;We are going to implement a simple Mocking library for &lt;a href="https://github.com/seattlerb/minitest"&gt;Minitest&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Given an 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="c1"&gt;# Test double&lt;/span&gt;
&lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We should be able to stub a method on this object and it will return our stubbed value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Stub&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:full?&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full?&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We should be able to mock an object (mock will verify if &lt;code&gt;removed&lt;/code&gt; was ever called, while stub does not do that check):&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;# Mock&lt;/span&gt;
&lt;span class="n"&gt;item_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1234&lt;/span&gt;
&lt;span class="n"&gt;assume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:remove&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why don‘t we use &lt;code&gt;expect(w).to receive(:remove).with(item_id)&lt;/code&gt; here, similar to RSpec? That‘s because Minitest has an &lt;a href="https://github.com/seattlerb/minitest/blob/6f53d4d986ce0acb1ba7e38ba1f2d010102ce8bf/lib/minitest/mock.rb#L71-L82"&gt;&lt;code&gt;#expect&lt;/code&gt; method&lt;/a&gt;, so let‘s avoid redefining it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design
&lt;/h2&gt;

&lt;p&gt;We will have two main classes - &lt;code&gt;StubTarget&lt;/code&gt; and &lt;code&gt;ExpectationDefinition&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Remember our Goal? In order to be able to do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:full?&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We‘ll break them up as follows using our two main 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="n"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;      &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:full?&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;^^^^^^^^^^^&lt;/span&gt;      &lt;span class="o"&gt;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;/span&gt;
&lt;span class="c1"&gt;#&amp;lt;StubTarget&amp;gt;    #&amp;lt;ExpectationDefinition&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Enough Ruby that You Need to Know
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Method Dispatch
&lt;/h3&gt;

&lt;p&gt;How does Ruby find methods? It climbs up the ancestors chain! When you invoke &lt;code&gt;to_s&lt;/code&gt; on object &lt;code&gt;object&lt;/code&gt;, Ruby asks &lt;code&gt;object&lt;/code&gt;...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ruby&lt;/strong&gt;: &lt;em&gt;Hey, do you have &lt;code&gt;to_s&lt;/code&gt; method?&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;object&lt;/strong&gt;: &lt;em&gt;Yup. I do.&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;Ruby&lt;/strong&gt;: &lt;em&gt;Awesome! Call it!&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;object&lt;/strong&gt;: &lt;em&gt;(invoking &lt;code&gt;to_s&lt;/code&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then it returns the result of &lt;code&gt;object.to_s&lt;/code&gt; which is &lt;code&gt;"#&amp;lt;Object:0x007fc0223b8280&amp;gt;"&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;#&amp;lt;Object:0x007fc0223b8280&amp;gt;&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"#&amp;lt;Object:0x007fc0223b8280&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://blog.jcoglan.com/2013/05/08/how-ruby-method-dispatch-works"&gt;More on Method Dispatch&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Ancestors Chain
&lt;/h3&gt;

&lt;p&gt;If Ruby can't find the method you want to call, it will climb up the ancestors chain, till it finds a class that responds to the message, otherwise it eventually throws a &lt;code&gt;NoMethodError&lt;/code&gt; exception.&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;object&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;ancestors&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&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="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# (searching from left to right)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Define a Method for a Specific Object
&lt;/h3&gt;

&lt;p&gt;Ruby has a singleton class for every object and you can define a method in the singleton class.&lt;/p&gt;

&lt;p&gt;The singleton class might be not visible in the ancestors chain above, but it's there.&lt;/p&gt;

&lt;h4&gt;
  
  
  Singleton Class
&lt;/h4&gt;

&lt;p&gt;The "Singleton Class" is easily confused with the &lt;a href="http://c2.com/cgi/wiki?SingletonPattern"&gt;Singleton&lt;/a&gt; design pattern.&lt;/p&gt;

&lt;p&gt;In fact, singleton class is an anonymous class attached to a specific object. Best illustrated with an example:&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;object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&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;def&lt;/span&gt; &lt;span class="nc"&gt;object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hello_world&lt;/span&gt;
  &lt;span class="s2"&gt;"Hello, World!"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hello_world&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "Hello, World!"&lt;/span&gt;

&lt;span class="n"&gt;another_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&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;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hello_world&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; NoMethodError (2)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, we are adding a &lt;code&gt;hello_world&lt;/code&gt; method to the &lt;code&gt;object&lt;/code&gt;. But the &lt;code&gt;hello_world&lt;/code&gt; method wasn't added to the &lt;code&gt;Object&lt;/code&gt; class (See (2) above).&lt;/p&gt;

&lt;p&gt;As you can see, Ruby insert the &lt;code&gt;hello_world&lt;/code&gt; method into &lt;code&gt;object&lt;/code&gt;'s singleton class!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.devalot.com/articles/2008/09/ruby-singleton"&gt;More on Singleton Class&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;code&gt;define_singleton_method&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;Another way to define a method for singleton class, is to use &lt;a href="http://ruby-doc.org/core-2.2.2/Object.html#method-i-define_singleton_method"&gt;&lt;code&gt;define_singleton_method(symbol, method_object)&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The example above could be re-written as follows:&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="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;#&amp;lt;Object:0x007fc0223b8280&amp;gt;&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;singleton_class&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;#&amp;lt;Class:#&amp;lt;Object:0x007fc0223b8280&amp;gt;&amp;gt;&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:hello_world&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"Hello, World!"&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;define_singleton_method&lt;/code&gt; accepts a method name and a &lt;a href="http://ruby-doc.org/core-2.2.2/Method.html"&gt;&lt;code&gt;Method&lt;/code&gt; object&lt;/a&gt;. Think of a Method object as similar to a &lt;code&gt;proc&lt;/code&gt; or &lt;code&gt;lambda&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's enough Ruby that you need to know. Yup. That's all!&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Mock Object Library
&lt;/h2&gt;

&lt;p&gt;Since this is a Mocking &lt;em&gt;library&lt;/em&gt;, let's make it a gem!&lt;/p&gt;

&lt;h3&gt;
  
  
  Your Mocking Gem
&lt;/h3&gt;

&lt;p&gt;Let's gemify our mocking library. You can name it using this pattern: &lt;code&gt;yourname_mock&lt;/code&gt;. My name is Juanito and so I will call it &lt;code&gt;juanito_mock&lt;/code&gt;, and we'll also use &lt;a href="http://bundler.io/v1.10/bundle_gem.html"&gt;&lt;code&gt;bundle gem&lt;/code&gt;&lt;/a&gt; command provided by &lt;a href="http://bundler.io"&gt;Bundler&lt;/a&gt; to create a skeleton of our gem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bundle gem juanito_mock &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;juanito_mock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that Bundler may prompt you to choose which test library you want to use, type &lt;code&gt;minitest&lt;/code&gt; and hit ENTER.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Creating gem &lt;span class="s1"&gt;'juanito_mock'&lt;/span&gt;...
MIT License enabled &lt;span class="k"&gt;in &lt;/span&gt;config
Do you want to generate tests with your gem?
Type &lt;span class="s1"&gt;'rspec'&lt;/span&gt; or &lt;span class="s1"&gt;'minitest'&lt;/span&gt; to generate those &lt;span class="nb"&gt;test &lt;/span&gt;files now and &lt;span class="k"&gt;in &lt;/span&gt;the future. rspec/minitest/&lt;span class="o"&gt;(&lt;/span&gt;none&lt;span class="o"&gt;)&lt;/span&gt;:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your generated skeleton gem has no tests or is generated with &lt;code&gt;spec&lt;/code&gt; folder, edit &lt;code&gt;~/.bundle/config&lt;/code&gt; file, add this line (or modify):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;BUNDLE_GEM__TEST: minitest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remove the generated folder and repeat it from the top again.&lt;/p&gt;

&lt;p&gt;The structure of the gem should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;├── Gemfile
├── LICENSE.txt
├── README.md
├── Rakefile
├── bin
│   ├── console
│   └── setup
├── juanito_mock.gemspec
├── lib
│   ├── juanito_mock
│   │   └── version.rb
│   └── juanito_mock.rb
└── &lt;span class="nb"&gt;test&lt;/span&gt;
    ├── juanito_mock_test.rb
    └── test_helper.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Why Minitest?
&lt;/h4&gt;

&lt;p&gt;Since we are implementing a RSpec-like mocking syntax, we don't want to use RSpec here so as to avoid confusions and conflicts with the original RSpec mocking library. Hence, we are going to use Minitest here to test our Mocking library.&lt;/p&gt;

&lt;p&gt;By the way, the correct spelling of Minitest is &lt;em&gt;Minitest&lt;/em&gt;, not &lt;em&gt;MiniTest&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Renamed MiniTest to Minitest. Your pinkies will thank me.&lt;br&gt;
&lt;a href="https://github.com/seattlerb/minitest/blob/master/History.rdoc#500--2013-05-10"&gt;Minitest 5.0.0 History&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Setup Minitest
&lt;/h3&gt;

&lt;p&gt;First lock Minitest to &lt;code&gt;5.8.0&lt;/code&gt; in gemspec's &lt;a href="http://guides.rubygems.org/specification-reference/#add_development_dependency"&gt;development dependency&lt;/a&gt; in order to use it in development:&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;spec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_development_dependency&lt;/span&gt; &lt;span class="s2"&gt;"minitest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"5.8.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Latest version of Minitest is &lt;code&gt;5.8.0&lt;/code&gt; as of 16th Aug 2015.&lt;/p&gt;

&lt;p&gt;Add these lines to &lt;code&gt;test/test_helper.rb&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"minitest/spec"&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"minitest/autorun"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reorder and your &lt;code&gt;test/test_helper.rb&lt;/code&gt; should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="vg"&gt;$LOAD_PATH&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unshift&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expand_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"../../lib"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"minitest/spec"&lt;/span&gt; &lt;span class="c1"&gt;# simple and clean spec system&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"minitest/autorun"&lt;/span&gt; &lt;span class="c1"&gt;# easy and explicit way to run all your tests&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"juanito_mock"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note on quotes of string. &lt;a href="https://viget.com/extend/just-use-double-quoted-ruby-strings"&gt;&lt;em&gt;Just Use double-quoted strings&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We use &lt;a href="http://docs.seattlerb.org/minitest/Minitest/Spec/DSL.html"&gt;Minitest/Spec&lt;/a&gt; syntax to write our tests and &lt;code&gt;require "minitest/autorun"&lt;/code&gt; to easily run all our tests.&lt;/p&gt;

&lt;p&gt;Next, delete the generated tests in &lt;code&gt;test/juanito_mock_test.rb&lt;/code&gt; and update it with DSL:&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="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"test_helper"&lt;/span&gt;

&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;JuanitoMock&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Now if you run &lt;code&gt;rake&lt;/code&gt;, you should have a working test suite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 55155

&lt;span class="c"&gt;# Running:&lt;/span&gt;


Finished &lt;span class="k"&gt;in &lt;/span&gt;0.000783s, 0.0000 runs/s, 0.0000 assertions/s.

0 runs, 0 assertions, 0 failures, 0 errors, 0 skips
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's write our first test!&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation of Stub
&lt;/h3&gt;

&lt;p&gt;Create a test case by using &lt;code&gt;it&lt;/code&gt; followed by a descriptive description string, and a block of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;JuanitoMock&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"allows an object to receive a message and returns a value"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;warehouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&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;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:full?&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;must_equal&lt;/span&gt; &lt;span class="kp"&gt;true&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;Let's walk through the code..&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Firstly, we create a new instance of &lt;code&gt;Object&lt;/code&gt; and assign it to a variable &lt;code&gt;warehouse&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:full?&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we create a stub that will receive the method &lt;code&gt;full?&lt;/code&gt; and return the result &lt;code&gt;true&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;must_equal&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we verify our stub is working by using &lt;a href="http://docs.seattlerb.org/minitest/Minitest/Expectations.html#method-i-must_equal"&gt;must_equal&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Sidenote: See the blank lines in our test? These blank lines are very important to distinguish different phases of the test.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://xunitpatterns.com/Four%20Phase%20Test.html"&gt;More on Four Phase Test&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  How to Run Tests
&lt;/h4&gt;

&lt;p&gt;First, let's take a look at &lt;code&gt;Rakefile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"bundler/gem_tasks"&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"rake/testtask"&lt;/span&gt;

&lt;span class="no"&gt;Rake&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;TestTask&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;:test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;libs&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"test"&lt;/span&gt;
  &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;libs&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"lib"&lt;/span&gt;
  &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test_files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;FileList&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'test/**/*_test.rb'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="ss"&gt;:default&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;require "rake/testtask"&lt;/code&gt; included in a file with a rake task defined (&lt;code&gt;rake test&lt;/code&gt;) that can run our tests easily via &lt;a href="https://github.com/ruby/rake"&gt;rake&lt;/a&gt;, see &lt;a href="http://ruby-doc.org/stdlib-2.2.2/libdoc/rake/rdoc/Rake/TestTask.html"&gt;Rake::TestTask&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;You can see a full list of rake tasks available by typing &lt;code&gt;rake -T&lt;/code&gt; in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake &lt;span class="nt"&gt;-T&lt;/span&gt;
rake build          &lt;span class="c"&gt;# Build juanito_mock-0.1.0.gem into the pkg directory&lt;/span&gt;
rake &lt;span class="nb"&gt;install&lt;/span&gt;        &lt;span class="c"&gt;# Build and install juanito_mock-0.1.0.gem into system ...&lt;/span&gt;
rake &lt;span class="nb"&gt;install&lt;/span&gt;:local  &lt;span class="c"&gt;# Build and install juanito_mock-0.1.0.gem into system ...&lt;/span&gt;
rake release        &lt;span class="c"&gt;# Create tag v0.1.0 and build and push juanito_mock-0.1...&lt;/span&gt;
rake &lt;span class="nb"&gt;test&lt;/span&gt;           &lt;span class="c"&gt;# Run tests&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;build&lt;/code&gt;, &lt;code&gt;install&lt;/code&gt;, &lt;code&gt;install:local&lt;/code&gt;, and &lt;code&gt;release&lt;/code&gt; tasks are provided by Bundler. See &lt;a href="https://github.com/bundler/bundler/blob/a490f6a1892e6033ed0f1a12a0c8c3e188518e8d/lib/bundler/gem_helper.rb#L37-L68"&gt;bundler/bundler lib/bundler/gem_helper.rb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But you also see that &lt;code&gt;rake test&lt;/code&gt; is available for use.&lt;/p&gt;

&lt;p&gt;To make it even simple to run your tests, the &lt;code&gt;Rakefile&lt;/code&gt; has this &lt;code&gt;task :default =&amp;gt; :test&lt;/code&gt; which basically maps the default rake task to running tests.&lt;/p&gt;

&lt;p&gt;This means that you can just type &lt;code&gt;rake&lt;/code&gt; instead of &lt;code&gt;rake test&lt;/code&gt; to run all your tests.&lt;/p&gt;

&lt;p&gt;Let's run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 49489

&lt;span class="c"&gt;# Running:&lt;/span&gt;

E

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.000963s, 1038.1963 runs/s, 0.0000 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0001_allows an object to receive a message and returns a value:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;allow&lt;span class="s1"&gt;' for #&amp;lt;#&amp;lt;Class:0x007fe04516bf70&amp;gt;:0x007fe045d001d8&amp;gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:7:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yay! Our first failing test, read the error carefully to find out what to do next:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;undefined method &lt;span class="sb"&gt;`&lt;/span&gt;allow&lt;span class="s1"&gt;' for #&amp;lt;#&amp;lt;Class:0x007fe04516bf70&amp;gt;:0x007fe045d001d8&amp;gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:7:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It even tells you which line to fix the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;test&lt;/span&gt;/juanito_mock_test.rb:7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;:7&lt;/code&gt; means line 7 from the file &lt;code&gt;test/juanito_mock_test.rb&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Add DSL to Minitest
&lt;/h4&gt;

&lt;p&gt;Let's proceed to fix the failing test.&lt;/p&gt;

&lt;p&gt;From Minitest README, we know every test in Minitest is a subclass of &lt;a href="https://github.com/seattlerb/minitest/blob/master/lib/minitest/test.rb"&gt;&lt;code&gt;Minitest::Test&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;To add method &lt;code&gt;allow&lt;/code&gt; to &lt;code&gt;Minitest::Test&lt;/code&gt;, all we have to do is to create a module &lt;code&gt;TestExtensions&lt;/code&gt; and include it in the &lt;code&gt;Minitest::Test&lt;/code&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="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"juanito_mock/version"&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;TestExtensions&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;allow&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;Minitest::Test&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;JuanitoMock&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;TestExtensions&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's run our test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 41300

&lt;span class="c"&gt;# Running:&lt;/span&gt;

E

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001002s, 997.6067 runs/s, 0.0000 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0001_allows an object to receive a message and returns a value:
ArgumentError: wrong number of arguments &lt;span class="o"&gt;(&lt;/span&gt;1 &lt;span class="k"&gt;for &lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:5:in &lt;span class="sb"&gt;`&lt;/span&gt;allow&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice! Now we get a different error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ArgumentError: wrong number of arguments &lt;span class="o"&gt;(&lt;/span&gt;1 &lt;span class="k"&gt;for &lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:5:in &lt;span class="sb"&gt;`&lt;/span&gt;allow&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The error occurs because we are calling &lt;code&gt;allow&lt;/code&gt; like so &lt;code&gt;allow(warehouse)&lt;/code&gt; in our code, which means we are passing in an argument &lt;code&gt;warehouse&lt;/code&gt; which our allow method doesn't accept yet.&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;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:full?&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's fix this by modifying our &lt;code&gt;allow&lt;/code&gt; method to accept an argument &lt;code&gt;obj&lt;/code&gt;. Then, we'll construct an instance of &lt;code&gt;StubTarget&lt;/code&gt; with the argument, as described in our design:&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="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"juanito_mock/version"&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;TestExtensions&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;StubTarget&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;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Minitest::Test&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;JuanitoMock&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;TestExtensions&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run the test again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 7548

&lt;span class="c"&gt;# Running:&lt;/span&gt;

E

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.000915s, 1092.3434 runs/s, 0.0000 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0001_allows an object to receive a message and returns a value:
NameError: uninitialized constant JuanitoMock::TestExtensions::StubTarget
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:6:in &lt;span class="sb"&gt;`&lt;/span&gt;allow&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another error this time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;NameError: uninitialized constant JuanitoMock::TestExtensions::StubTarget
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:6:in &lt;span class="sb"&gt;`&lt;/span&gt;allow&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ruby is now complaining that it can't find the constant &lt;code&gt;JuanitoMock::TestExtensions::StubTarget&lt;/code&gt;. Of course! That's because we haven't define &lt;code&gt;StubTarget&lt;/code&gt; class yet, so let's define it:&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;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StubTarget&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;TestExtensions&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;StubTarget&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;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Minitest::Test&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;JuanitoMock&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;TestExtensions&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a start, we will just save the &lt;code&gt;obj&lt;/code&gt; in an instance variable.&lt;/p&gt;

&lt;p&gt;Now run the test again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 25153

&lt;span class="c"&gt;# Running:&lt;/span&gt;

E

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001059s, 944.4913 runs/s, 0.0000 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0001_allows an object to receive a message and returns a value:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;receive&lt;span class="s1"&gt;' for #&amp;lt;#&amp;lt;Class:0x007fe080b5d430&amp;gt;:0x007fe081057058&amp;gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What? Another error. This doesn't seem like it's ending soon. But you should actually rejoice, because we now have a different error, and that means we are progressing!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;receive&lt;span class="s1"&gt;' for #&amp;lt;#&amp;lt;Class:0x007fe080b5d430&amp;gt;:0x007fe081057058&amp;gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time it's ranting about another missing method &lt;code&gt;receive&lt;/code&gt;. Hmm what about &lt;code&gt;to&lt;/code&gt;? Why didn't it complain about a missing method &lt;code&gt;to&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;That's because Ruby always tries to evaluate the right-hand side first, and so it's going to process &lt;code&gt;receive&lt;/code&gt; first before it gets to &lt;code&gt;to&lt;/code&gt;. Dont' worry, you'll see an error for &lt;code&gt;to&lt;/code&gt; later.&lt;/p&gt;

&lt;p&gt;Let's define a &lt;code&gt;receive&lt;/code&gt; method in &lt;code&gt;TestExtensions&lt;/code&gt; module which accepts a message:&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="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"juanito_mock/version"&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StubTarget&lt;/span&gt;
    &lt;span class="o"&gt;...&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;TestExtensions&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&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;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;ExpectationDefinition&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;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As described in design section, &lt;code&gt;receive&lt;/code&gt; will return a &lt;code&gt;ExpectationDefinition&lt;/code&gt; instance.&lt;/p&gt;

&lt;p&gt;Now run the test again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 27383

&lt;span class="c"&gt;# Running:&lt;/span&gt;

E

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001145s, 873.0986 runs/s, 0.0000 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0001_allows an object to receive a message and returns a value:
NameError: uninitialized constant JuanitoMock::TestExtensions::ExpectationDefinition
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:16:in &lt;span class="sb"&gt;`&lt;/span&gt;receive&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You probably already expected it and now Ruby complains that it cannot find &lt;code&gt;ExpectationDefinition&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;NameError: uninitialized constant JuanitoMock::TestExtensions::ExpectationDefinition
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:16:in &lt;span class="sb"&gt;`&lt;/span&gt;receive&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's go ahead and define it, keeping &lt;code&gt;ExpectationDefinition&lt;/code&gt; simple, such that it only accepts an argument and stores it in an instance variable.&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;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StubTarget&lt;/span&gt;
    &lt;span class="o"&gt;...&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;ExpectationDefinition&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;TestExtensions&lt;/span&gt;
    &lt;span class="o"&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;Now run the test again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 47423

&lt;span class="c"&gt;# Running:&lt;/span&gt;

E

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001005s, 995.4657 runs/s, 0.0000 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0001_allows an object to receive a message and returns a value:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;and_return&lt;span class="s1"&gt;' for #&amp;lt;JuanitoMock::ExpectationDefinition:0x007fe072f6a798&amp;gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now Ruby cannot find the &lt;code&gt;and_return&lt;/code&gt; method&lt;br&gt;
(poor Ruby, thanks for doing so much work for us 😢):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NoMethodError: undefined method `and_return' for #&amp;lt;JuanitoMock::ExpectationDefinition:0x007fe072f6a798&amp;gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looking at the error, it's actually telling us that it cannot find the &lt;code&gt;and_return&lt;/code&gt; method on &lt;code&gt;ExpectationDefinition&lt;/code&gt;, so let's define it there:&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="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"juanito_mock/version"&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StubTarget&lt;/span&gt;
    &lt;span class="o"&gt;...&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;ExpectationDefinition&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message&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;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;return_value&lt;/span&gt;
      &lt;span class="nb"&gt;self&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;TestExtensions&lt;/span&gt;
    &lt;span class="o"&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;This new method &lt;code&gt;and_return&lt;/code&gt; is interesting and contains the secret to enabling method chaining.&lt;/p&gt;

&lt;p&gt;Do you know what it is?&lt;/p&gt;

&lt;p&gt;Yes. The method is returning &lt;code&gt;self&lt;/code&gt;!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="vi"&gt;@return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;return_value&lt;/span&gt;
  &lt;span class="nb"&gt;self&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the magic to building a chaining interface for your objects! All you have to do is to build up objects and return &lt;code&gt;self&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;Now let's run our test again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 11338

&lt;span class="c"&gt;# Running:&lt;/span&gt;

E

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001084s, 922.9213 runs/s, 0.0000 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0001_allows an object to receive a message and returns a value:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;to&lt;span class="s1"&gt;' for #&amp;lt;JuanitoMock::StubTarget:0x007ff48a516590&amp;gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes! Now we see the error for undefined method &lt;code&gt;to&lt;/code&gt; on &lt;code&gt;StubTarget&lt;/code&gt; class, and so let's define the &lt;code&gt;to&lt;/code&gt; method on &lt;code&gt;StubTarget&lt;/code&gt; class according to our design:&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;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:full?&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;^^^^^^^^^^^^^^^^&lt;/span&gt;    &lt;span class="o"&gt;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;/span&gt;
    &lt;span class="no"&gt;StubTarget&lt;/span&gt;            &lt;span class="no"&gt;ExpectationDefinition&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where the &lt;code&gt;to&lt;/code&gt; method accepts an &lt;code&gt;ExpectationDefinition&lt;/code&gt; object as argument.&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;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StubTarget&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;obj&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;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&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;class&lt;/span&gt; &lt;span class="nc"&gt;ExpectationDefinition&lt;/span&gt;
    &lt;span class="o"&gt;...&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;TestExtensions&lt;/span&gt;
    &lt;span class="o"&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;Now let's run our test again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 31564

&lt;span class="c"&gt;# Running:&lt;/span&gt;

E

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001092s, 915.9027 runs/s, 0.0000 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0001_allows an object to receive a message and returns a value:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;full?&lt;span class="s1"&gt;' for #&amp;lt;Object:0x007f8fcc47dc28&amp;gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:11:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reading our next failure, the error guides us to define a &lt;code&gt;full?&lt;/code&gt; method on the object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;full?&lt;span class="s1"&gt;' for #&amp;lt;Object:0x007f8fcc47dc28&amp;gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:11:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's use the aforementioned &lt;code&gt;define_singleton_method&lt;/code&gt; magic to define the &lt;code&gt;full?&lt;/code&gt; method, and which returns the expected value of &lt;code&gt;true&lt;/code&gt; as specified in our test:&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;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StubTarget&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;return_value&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;ExpectationDefinition&lt;/span&gt;
    &lt;span class="o"&gt;...&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;TestExtensions&lt;/span&gt;
    &lt;span class="o"&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;Now run the tests again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 14082

&lt;span class="c"&gt;# Running:&lt;/span&gt;

E

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001091s, 916.4954 runs/s, 0.0000 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0001_allows an object to receive a message and returns a value:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;message&lt;span class="s1"&gt;' for #&amp;lt;JuanitoMock::ExpectationDefinition:0x007ff31d8ae220&amp;gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:10:in `to'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="o"&gt;(&lt;/span&gt;2 levels&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &amp;lt;top &lt;span class="o"&gt;(&lt;/span&gt;required&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status (1): [ruby -I"lib:test:lib"  "/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb" "test/juanito_mock_test.rb" ]

Tasks: TOP =&amp;gt; default =&amp;gt; test
(See full trace by running task with --trace)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time Ruby cannot find &lt;code&gt;message&lt;/code&gt; on &lt;code&gt;ExpectationDefinition&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;message&lt;span class="s1"&gt;' for #&amp;lt;JuanitoMock::ExpectationDefinition:0x007ff31d8ae220&amp;gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:10:in `to'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="o"&gt;(&lt;/span&gt;2 levels&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &amp;lt;top &lt;span class="o"&gt;(&lt;/span&gt;required&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keeping it simple, we expose &lt;code&gt;message&lt;/code&gt; and &lt;code&gt;return_value&lt;/code&gt; in &lt;code&gt;ExpectationDefinition&lt;/code&gt; class with &lt;code&gt;attr_reader&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExpectationDefinition&lt;/span&gt;
    &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:return_value&lt;/span&gt;

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

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

  &lt;span class="o"&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;Now run this test again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 46498

&lt;span class="c"&gt;# Running:&lt;/span&gt;

&lt;span class="nb"&gt;.&lt;/span&gt;

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.000975s, 1025.2078 runs/s, 1025.2078 assertions/s.

1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our first passing test!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fdBwrD0w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dl.dropboxusercontent.com/s/axnvpjzylwmvju0/woohoo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fdBwrD0w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dl.dropboxusercontent.com/s/axnvpjzylwmvju0/woohoo.jpg" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:full?&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line in the test is actually passing! Just with 42 lines of code in a relatively short amount of time!&lt;/p&gt;

&lt;p&gt;Let's take a step back to see what we have done so far. Basically, we started to build our Mocking library by writing a test - a failing test. Then we write some code to error that was thrown, and some more code to fix the next error that was thrown and so on and so forth. And finally, through our persistence, we got the test to pass!&lt;/p&gt;

&lt;p&gt;This practice of writing software is what we call Test Driven Development (TDD), where we go from red (failing test), to green (passing test) and moving on to refactor. This is a practice that a lot of software engineers embrace, and it's one which we have found immense benefits when doing it consistently.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Edge of Mocking
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XrRaWTN7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dl.dropboxusercontent.com/s/8zpeh5ejh182d3e/edgeoftomorrow.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XrRaWTN7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dl.dropboxusercontent.com/s/8zpeh5ejh182d3e/edgeoftomorrow.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Are we done already? Not quite!&lt;/p&gt;

&lt;p&gt;In our current code, we defined the &lt;code&gt;full?&lt;/code&gt;method on the object when the test starts, but we didn't do anything to reset our change after the test finishes, and that's actually not so good, because it might affect other tests. So, we should reset the state and unset the &lt;code&gt;full?&lt;/code&gt; method that we have "stubbed".&lt;/p&gt;

&lt;p&gt;Let's write another test for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"removes stubbed method after tests finished"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;warehouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&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;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:full?&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="no"&gt;JuanitoMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;

    &lt;span class="n"&gt;assert_raises&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;NoMethodError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full?&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;&lt;em&gt;I intentionally prefix each line with two spaces to make it copy-paste friendly, but I strongly encourage you to type on your own.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the above test, we invoke &lt;code&gt;JuanitoMock.reset&lt;/code&gt; to clear/undo all changes to the code, and we verify this by using &lt;a href="http://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-assert_raises"&gt;&lt;code&gt;assert_raises&lt;/code&gt;&lt;/a&gt; where we test that an exception is raised&lt;br&gt;
when &lt;code&gt;full?&lt;/code&gt; is invoked.&lt;/p&gt;

&lt;p&gt;At this point, this is how your test file should look like:&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="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"test_helper"&lt;/span&gt;

&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;JuanitoMock&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"allows an object to receive a message and returns a value"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;warehouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&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;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:full?&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;must_equal&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"removes stubbed method after tests finished"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;warehouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&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;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:full?&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="no"&gt;JuanitoMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;

    &lt;span class="n"&gt;assert_raises&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;NoMethodError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full?&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once again, we run the test to find out what to do next:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 30441

&lt;span class="c"&gt;# Running:&lt;/span&gt;

.E

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001152s, 1736.7443 runs/s, 868.3721 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0002_removes stubbed method after tests finished:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;reset&lt;span class="s1"&gt;' for JuanitoMock:Module
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:17:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

2 runs, 1 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oops. Did you expect that - undefined method &lt;code&gt;reset&lt;/code&gt; for &lt;code&gt;JuanitoMock:Module&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Let's write this method! Edit &lt;code&gt;lib/juanito_mock.rb&lt;/code&gt; and add this module-level method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;TestExtensions&lt;/span&gt;
    &lt;span class="o"&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;reset&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;What do we do next? What should we write in the method? Run the test and let that help us!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 22585

&lt;span class="c"&gt;# Running:&lt;/span&gt;

.F

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001207s, 1657.1930 runs/s, 1657.1930 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Failure:
JuanitoMock#test_0002_removes stubbed method after tests finished &lt;span class="o"&gt;[&lt;/span&gt;/Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:19]:
NoMethodError expected but nothing was raised.

2 runs, 2 assertions, 1 failures, 0 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;NoMethodError expected but nothing was raised.&lt;/code&gt;. Yup. That's what I expected, too.&lt;/p&gt;

&lt;p&gt;How can we undefine the method &lt;code&gt;full?&lt;/code&gt; that we have stubbed on the object? As we had defined the method &lt;code&gt;full?&lt;/code&gt; in the object's singleton class, there is actually no reference to it and so we don't know how to undefine it, at least for now...&lt;/p&gt;

&lt;p&gt;Let's park that for now, and do something else instead (which would help us later).&lt;/p&gt;

&lt;p&gt;Let's improve the code!&lt;/p&gt;

&lt;p&gt;We are going to make some changes to our code without losing the any of our current functionality.&lt;/p&gt;

&lt;p&gt;Let's start by wrapping the define method step into a class, a delegate class and name it: &lt;code&gt;Stubber&lt;/code&gt;. Put &lt;code&gt;Stubber&lt;/code&gt; below &lt;code&gt;StubTarget&lt;/code&gt; and above the &lt;code&gt;ExpectationDefinition&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StubTarget&lt;/span&gt;
    &lt;span class="o"&gt;...&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;Stubber&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;obj&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;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&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;class&lt;/span&gt; &lt;span class="nc"&gt;ExpectationDefinition&lt;/span&gt;
    &lt;span class="o"&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;Then, move the implementation of &lt;code&gt;StubTarget#to&lt;/code&gt; to &lt;code&gt;Stubber#stub&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StubTarget&lt;/span&gt;
    &lt;span class="o"&gt;...&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;Stubber&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;obj&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;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;return_value&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;ExpectationDefinition&lt;/span&gt;
    &lt;span class="o"&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;In &lt;code&gt;StubTarget#to&lt;/code&gt;, we delegate the job to &lt;code&gt;Stubber#stub&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StubTarget&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;Stubber&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="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&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="o"&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;Nice &lt;a href="http://c2.com/cgi/wiki?WhatIsRefactoring"&gt;refactoring&lt;/a&gt;! This is an essential step in the TDD practice, and what we just did was basically to improve our code without modifying the current feature set of our code. We can verify this by running our tests which would prove that the first test is green, while the second test is still red:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 23169

&lt;span class="c"&gt;# Running:&lt;/span&gt;

.F

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001183s, 1691.2146 runs/s, 1691.2146 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Failure:
JuanitoMock#test_0002_removes stubbed method after tests finished &lt;span class="o"&gt;[&lt;/span&gt;/Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:19]:
NoMethodError expected but nothing was raised.

2 runs, 2 assertions, 1 failures, 0 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's get back to fixing the error.&lt;/p&gt;

&lt;p&gt;Let's store what we stubbed in an array called &lt;code&gt;@definitions&lt;/code&gt;, in &lt;code&gt;Stubber#stub&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stubber&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;
      &lt;span class="vi"&gt;@definitions&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;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@definitions&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;

      &lt;span class="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;return_value&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="o"&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;However, having the &lt;code&gt;@definitions&lt;/code&gt; array is not enough because the &lt;code&gt;Stubber&lt;/code&gt; instance in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;Stubber&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="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&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;immediately goes out of scope and gets garbage collected, and so we still do not have a list of all methods that were stubbed.&lt;/p&gt;

&lt;p&gt;Hence we need to be able to save the &lt;code&gt;Stubber&lt;/code&gt; instance(s) by using a &lt;code&gt;Stubber.for_object&lt;/code&gt; class-level method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StubTarget&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;obj&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;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;Stubber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;for_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&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="o"&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;Now run the test again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 37100

&lt;span class="c"&gt;# Running:&lt;/span&gt;

EE

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001317s, 1518.4864 runs/s, 0.0000 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0002_removes stubbed method after tests finished:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;for_object&lt;span class="s1"&gt;' for JuanitoMock::Stubber:Class
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:10:in `to'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:15:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="o"&gt;(&lt;/span&gt;2 levels&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &amp;lt;top &lt;span class="o"&gt;(&lt;/span&gt;required&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'


  2) Error:
JuanitoMock#test_0001_allows an object to receive a message and returns a value:
NoMethodError: undefined method `for_object'&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;JuanitoMock::Stubber:Class
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:10:in &lt;span class="sb"&gt;`&lt;/span&gt;to&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:7:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

2 runs, 0 assertions, 0 failures, 2 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next error to fix is to define &lt;code&gt;for_object&lt;/code&gt; on &lt;code&gt;Stubber&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;for_object&lt;span class="s1"&gt;' for JuanitoMock::Stubber:Class
  /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:10:in `to'&lt;/span&gt;
  /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:7:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="o"&gt;(&lt;/span&gt;2 levels&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;Stubber.for_object&lt;/code&gt; method is a custom initializer for the &lt;code&gt;Stubber&lt;/code&gt; class that will not only create &lt;code&gt;Stubber&lt;/code&gt; instances, but also store them in a lazily-initialized hash, with its &lt;a href="http://ruby-doc.org/core-2.2.2/Object.html#method-i-object_id"&gt;&lt;code&gt;object_id&lt;/code&gt;&lt;/a&gt; as key:&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;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stubber&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;stubbers&lt;/span&gt;
      &lt;span class="vi"&gt;@stubbers&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="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;for_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;stubbers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;__id__&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="no"&gt;Stubber&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;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="o"&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;But are we making progress for &lt;code&gt;JuanitoMock.reset&lt;/code&gt;? Hmm.. Let's run the tests first.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 4701

&lt;span class="c"&gt;# Running:&lt;/span&gt;

.F

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001117s, 1789.8854 runs/s, 1789.8854 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Failure:
JuanitoMock#test_0002_removes stubbed method after tests finished &lt;span class="o"&gt;[&lt;/span&gt;/Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:19]:
NoMethodError expected but nothing was raised.

2 runs, 2 assertions, 1 failures, 0 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The failure is still the same as before, but we are actually making a progress.&lt;/p&gt;

&lt;p&gt;Given that all the stubbed methods are now stored in the &lt;code&gt;Stubber&lt;/code&gt; class, it would be great if we have one single method in &lt;code&gt;Stubber&lt;/code&gt; that can help us. Thinking along that line of thought, let's have a &lt;code&gt;Stubber.reset&lt;/code&gt; method that does exactly that, and then it would be trivial for &lt;code&gt;JuanitoMock.reset&lt;/code&gt; to invoke it!&lt;/p&gt;

&lt;p&gt;Let's try to implement the logic for &lt;code&gt;Stubber.reset&lt;/code&gt; that &lt;a href="http://c2.com/cgi/wiki?WishfulThinking"&gt;we wish we have&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;stubbers&lt;/code&gt; currently is a hash that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="mi"&gt;70173643198180&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;#&amp;lt;Stubber instance&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;It is a one-to-one object id mapping to a &lt;code&gt;Stubber&lt;/code&gt; instance. We would first want each instance to unstub the method that we stub earlier. The intent is still similar, so each instance should have its own &lt;code&gt;reset&lt;/code&gt; method that we can call. Also, the &lt;code&gt;reset&lt;/code&gt; method should empty the hash after we are done with it.&lt;br&gt;
Cool! Ruby has a &lt;a href="http://ruby-doc.org/core-2.2.2/Hash.html#method-i-clear"&gt;&lt;code&gt;clear&lt;/code&gt;&lt;/a&gt; method that we can use.&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;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stubber&lt;/span&gt;
    &lt;span class="o"&gt;...&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;for_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&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;reset&lt;/span&gt;
      &lt;span class="n"&gt;stubbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:reset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;stubbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

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

  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;TestExtensions&lt;/span&gt;
    &lt;span class="o"&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;reset&lt;/span&gt;
    &lt;span class="no"&gt;Stubber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&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;Run the tests again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 11282

&lt;span class="c"&gt;# Running:&lt;/span&gt;

.E

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001142s, 1751.6509 runs/s, 875.8255 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0002_removes stubbed method after tests finished:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;reset&lt;span class="s1"&gt;' for #&amp;lt;JuanitoMock::Stubber:0x007f9a85c7bf38&amp;gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:24:in `each_value'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:24:in &lt;span class="sb"&gt;`&lt;/span&gt;reset&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:66:in `reset'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:17:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="o"&gt;(&lt;/span&gt;2 levels&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &amp;lt;top &lt;span class="o"&gt;(&lt;/span&gt;required&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'

2 runs, 1 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status (1): [ruby -I"lib:test:lib"  "/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb" "test/juanito_mock_test.rb" ]

Tasks: TOP =&amp;gt; default =&amp;gt; test
(See full trace by running task with --trace)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have an undefined method &lt;code&gt;reset&lt;/code&gt; for &lt;code&gt;#&amp;lt;JuanitoMock::Stubber:0x007f9a85c7bf38&amp;gt;&lt;/code&gt; - a &lt;code&gt;Stubber&lt;/code&gt; instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JuanitoMock#test_0002_removes stubbed method after tests finished:
NoMethodError: undefined method `reset' for #&amp;lt;JuanitoMock::Stubber:0x007f9a85c7bf38&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's implement &lt;code&gt;Stubber#reset&lt;/code&gt;. In &lt;code&gt;Stubber#reset&lt;/code&gt;, what we need to do is to undefine/unstub the method we have defined/stubbed earlier.&lt;/p&gt;

&lt;p&gt;In Ruby, we can use &lt;a href="http://ruby-doc.org/core-2.2.0/Module.html#method-i-remove_method"&gt;remove_method&lt;/a&gt; with some &lt;a href="http://ruby-doc.org/core-2.2.0/Module.html#method-i-class_eval"&gt;class_eval&lt;/a&gt; craziness to achieve this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stubber&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&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;reset&lt;/span&gt;
      &lt;span class="vi"&gt;@definitions&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;definition&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;singleton_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class_eval&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="n"&gt;remove_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;method_defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;We avoid the &lt;code&gt;NoMethodError&lt;/code&gt; exception by checking &lt;a href="http://ruby-doc.org/core-2.2.0/Module.html#method-i-method_defined-3F"&gt;method_defined?&lt;/a&gt; on &lt;code&gt;definition.message&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now if you are brave enough to run the tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 55448

&lt;span class="c"&gt;# Running:&lt;/span&gt;

..

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001233s, 1622.4943 runs/s, 1622.4943 assertions/s.

2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You shall see all our tests passed! All green! Yay!!!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hLk3Szt0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dl.dropboxusercontent.com/s/k97ohji8iqlmmxb/thegreatgatsby.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hLk3Szt0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dl.dropboxusercontent.com/s/k97ohji8iqlmmxb/thegreatgatsby.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All tests passed, old sport! Can we live happily ever after now? Hmm...&lt;/p&gt;

&lt;h2&gt;
  
  
  Blindly Removing Methods
&lt;/h2&gt;

&lt;p&gt;Till now, we have covered the cases of stubbing and unstubbing. But there's actually a third case to consider!&lt;/p&gt;

&lt;p&gt;What if, at the very beginning, there was already a &lt;code&gt;full?&lt;/code&gt; method defined? We would have "killed" or "replaced" the original method unknowingly.&lt;/p&gt;

&lt;p&gt;Let's write another test to describe this case:&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;it&lt;/span&gt; &lt;span class="s2"&gt;"preserves methods that originally existed"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;warehouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&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;def&lt;/span&gt; &lt;span class="nc"&gt;warehouse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="c1"&gt;# defining methods on Ruby singleton class&lt;/span&gt;

    &lt;span class="n"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:full?&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="no"&gt;JuanitoMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;

    &lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;must_equal&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 4474

&lt;span class="c"&gt;# Running:&lt;/span&gt;

.E.

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001266s, 2369.2790 runs/s, 1579.5193 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0003_preserves methods that are originally existed:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;full?&lt;span class="s1"&gt;' for #&amp;lt;Object:0x007fcdcd4d3b70&amp;gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:29:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

3 runs, 2 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have a failure on our new test!&lt;/p&gt;

&lt;p&gt;What happened was that our stub &lt;code&gt;allow(warehouse).to receive(:full?).and_return(true)&lt;/code&gt; replaced the original method, and when we called &lt;code&gt;JuanitoMock.reset&lt;/code&gt;, it only removed the stub but didn't bring back the original implementation for &lt;code&gt;full?&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Hence the &lt;code&gt;NoMethodError&lt;/code&gt; exception is expected, because the method's basically gone!&lt;/p&gt;

&lt;p&gt;This is not ok. Let's fix that. But first let's take a look at &lt;code&gt;Stubber#stub&lt;/code&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stubber&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@definitions&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;

    &lt;span class="c1"&gt;# preserve original method if already exists&lt;/span&gt;

    &lt;span class="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;return_value&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="o"&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 our current implementation of &lt;code&gt;Stubber#stub&lt;/code&gt;, we didn't check if the object already has the method or not and we just simply (re)defined the singleton method.&lt;/p&gt;

&lt;p&gt;We should preserve the original method if it already exists like so:&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;Stubber&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@definitions&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;singleton_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;method_defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@preserved_methods&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;
          &lt;span class="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;singleton_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;return_value&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="o"&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;Let's walk through what we just did:&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="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;singleton_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The magic comes from the use of &lt;a href="http://ruby-doc.org/core-2.2.0/Module.html#method-i-instance_method"&gt;Module#instance_method&lt;/a&gt; which will return a method object of given name from the singleton class.&lt;/p&gt;

&lt;p&gt;Think of this method object as a &lt;code&gt;proc&lt;/code&gt; or &lt;code&gt;lambda&lt;/code&gt; which we then we store in a &lt;code&gt;@preserved_methods&lt;/code&gt; array:&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;Stubber&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;
      &lt;span class="vi"&gt;@definitions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
      &lt;span class="vi"&gt;@preserved_methods&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="o"&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;Preserving the orignal method is only one part of the solution.&lt;/p&gt;

&lt;p&gt;When we do a &lt;code&gt;Stubber#reset&lt;/code&gt;, we actually want to reinstate and redefine these saved preserved methods:&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;Stubber&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reset&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;

      &lt;span class="vi"&gt;@preserved_methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reverse_each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use &lt;code&gt;reverse_each&lt;/code&gt; here because we need to preserve the original order of the methods. You can write a test here too to see the importance of using &lt;code&gt;reverse_each&lt;/code&gt; but we'll leave it as an exercise!&lt;/p&gt;

&lt;p&gt;P.S. Did you know &lt;a href="https://github.com/JuanitoFatas/fast-ruby#enumerablereverseeach-vs-enumerablereverse_each-code"&gt;reverse_each is more efficient than reverse.each?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;Stubber#stub&lt;/code&gt;, we used &lt;code&gt;obj.define_singleton_method&lt;/code&gt; with a block, but it also pairs really well with method objects that we are dealing with in the &lt;code&gt;@preserved_methods&lt;/code&gt; array.&lt;/p&gt;

&lt;p&gt;Every method object &lt;a href="http://ruby-doc.org/core-2.2.0/Module.html#method-i-instance_method"&gt;Method#instance_method&lt;/a&gt; has a &lt;a href="http://ruby-doc.org/core-2.2.0/Method.html#method-i-name"&gt;Method#name&lt;/a&gt; method that returns the name of the method. We can simply redefine the method by calling &lt;code&gt;define_singleton_method&lt;/code&gt; with the method name and the method object itself.&lt;/p&gt;

&lt;p&gt;Run the tests again and we should have three passing tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 63328

&lt;span class="c"&gt;# Running:&lt;/span&gt;

...

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001223s, 2453.9275 runs/s, 2453.9275 assertions/s.

3 runs, 3 assertions, 0 failures, 0 errors, 0 skips
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This also means we have successfully restored the original methods after the tests!&lt;/p&gt;

&lt;p&gt;Congrats on getting so far, but we are not quite done. By now we have only implemented &lt;code&gt;stub&lt;/code&gt; (and unstub), and next we are going to implement &lt;code&gt;mock&lt;/code&gt; - which is an expectation that a message will be received.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://en.wikipedia.org/wiki/To_Mock_a_Mockingbird"&gt;To Mock a Mockingbird&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NlYb6x0L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dl.dropboxusercontent.com/s/026xfo6671a8kyt/mockingbird.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NlYb6x0L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dl.dropboxusercontent.com/s/026xfo6671a8kyt/mockingbird.jpg" alt="https://en.wikipedia.org/wiki/Mockingbird"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's start with a new failing test as usual:&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;it&lt;/span&gt; &lt;span class="s2"&gt;"expects that a message will be received"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;warehouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&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;assume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:empty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# warehouse.empty not called!&lt;/span&gt;

    &lt;span class="n"&gt;assert_raises&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;JuanitoMock&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ExpectationNotSatisfied&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="no"&gt;JuanitoMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&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;In our test, &lt;code&gt;assume(warehouse).to receive(:empty)&lt;/code&gt; expects that &lt;code&gt;warehouse.empty&lt;/code&gt; will be invoked. However we are not actually going to call the &lt;code&gt;empty&lt;/code&gt; method and so, we assert that a custom exception &lt;code&gt;JuanitoMock::ExpectationNotSatisfied&lt;/code&gt; will be raised when we call &lt;code&gt;JuanitoMock.reset&lt;/code&gt; which loops and verfies each expectation.&lt;/p&gt;

&lt;p&gt;Let's run the test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 30442

&lt;span class="c"&gt;# Running:&lt;/span&gt;

..E.

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001308s, 3058.4267 runs/s, 2293.8200 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0004_expects that a message will be received:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;assume&lt;span class="s1"&gt;' for #&amp;lt;#&amp;lt;Class:0x007facec071a20&amp;gt;:0x007facecbea5a0&amp;gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:35:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

4 runs, 3 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first thing we see is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NoMethodError: undefined method `assume' for #&amp;lt;#&amp;lt;Class:0x007facec071a20&amp;gt;:0x007facecbea5a0&amp;gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:35:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have not define &lt;code&gt;assume&lt;/code&gt; in our &lt;code&gt;TestExtensions&lt;/code&gt; module, hence the error message. Let's do that! (&lt;code&gt;TestExtensions&lt;/code&gt; should be at the bottom of &lt;code&gt;lib/juanito_mock.rb&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;TestExtensions&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&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;assume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&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;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;
    &lt;span class="o"&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;Instead of an instance of &lt;code&gt;StubTarget&lt;/code&gt;, let's return an instance of &lt;code&gt;ExpectationTarget&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;TestExtensions&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;assume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;ExpectationTarget&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;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="o"&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;reset&lt;/span&gt;
    &lt;span class="o"&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;Now if you run the tests, it will complain that &lt;code&gt;ExpectationTarget&lt;/code&gt; is undefined:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 58985

&lt;span class="c"&gt;# Running:&lt;/span&gt;

...E

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001235s, 3237.5687 runs/s, 2428.1766 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0004_expects that a message will be received:
NameError: uninitialized constant JuanitoMock::TestExtensions::ExpectationTarget
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:79:in &lt;span class="sb"&gt;`&lt;/span&gt;assume&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:35:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

4 runs, 3 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use &lt;code&gt;ExpectationTarget&lt;/code&gt; in &lt;code&gt;assume&lt;/code&gt; because it's a target of a mock expectation (vs. a stub). However, &lt;code&gt;ExpectationTarget&lt;/code&gt; is actully very similar to a &lt;code&gt;StubTarget&lt;/code&gt; (a specialized form of &lt;code&gt;StubTarget&lt;/code&gt;), in that both stubs the original method implementation of an object, but &lt;code&gt;ExpectationTarget&lt;/code&gt; does a little something extra by checking that the message has been called.&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;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;assume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hence we can make &lt;code&gt;ExpectationTarget&lt;/code&gt; a subclass of &lt;code&gt;StubTarget&lt;/code&gt;, and let &lt;code&gt;to&lt;/code&gt; method in &lt;code&gt;ExpectationTarget&lt;/code&gt; inherit the implementation of &lt;code&gt;to&lt;/code&gt; method in &lt;code&gt;StubTarget&lt;/code&gt; by using &lt;code&gt;super&lt;/code&gt;. Then we also store the &lt;code&gt;definition&lt;/code&gt; object to a not-yet-exist &lt;code&gt;JuanitoMock.expectations&lt;/code&gt; array, so that we can use that to perform our expectation checks later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StubTarget&lt;/span&gt;
    &lt;span class="o"&gt;...&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;ExpectationTarget&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;StubTarget&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;super&lt;/span&gt;
      &lt;span class="no"&gt;JuanitoMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expectations&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;definition&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;Now run the tests again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 53163

&lt;span class="c"&gt;# Running:&lt;/span&gt;

...E

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001286s, 3109.3585 runs/s, 2332.0189 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0004_expects that a message will be received:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;expectations&lt;span class="s1"&gt;' for JuanitoMock:Module
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:17:in `to'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:35:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="o"&gt;(&lt;/span&gt;2 levels&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &amp;lt;top &lt;span class="o"&gt;(&lt;/span&gt;required&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'

4 runs, 3 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status (1): [ruby -I"lib:test:lib"  "/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb" "test/juanito_mock_test.rb" ]

Tasks: TOP =&amp;gt; default =&amp;gt; test
(See full trace by running task with --trace)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You know the drill. Let's initialize the &lt;code&gt;expectations&lt;/code&gt; array, lazily:&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;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;TestExtensions&lt;/span&gt;
    &lt;span class="o"&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;reset&lt;/span&gt;
    &lt;span class="no"&gt;Stubber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&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;expectations&lt;/span&gt;
    &lt;span class="vi"&gt;@expectations&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the tests once more and make a little bit more progress:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 51829

&lt;span class="c"&gt;# Running:&lt;/span&gt;

.E..

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001005s, 3980.0243 runs/s, 2985.0182 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0004_expects that a message will be received:
NameError: uninitialized constant JuanitoMock::ExpectationNotSatisfied
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:39:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="o"&gt;(&lt;/span&gt;2 levels&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &amp;lt;top &lt;span class="o"&gt;(&lt;/span&gt;required&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'

4 runs, 3 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status (1): [ruby -I"lib:test:lib"  "/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb" "test/juanito_mock_test.rb" ]

Tasks: TOP =&amp;gt; default =&amp;gt; test
(See full trace by running task with --trace)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where's the class &lt;code&gt;JuanitoMock::ExpectationNotSatisfied&lt;/code&gt;? Oops we don't have that yet, so let's fix it:&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;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="no"&gt;ExpectationNotSatisfied&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;StandardError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StubTarget&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="o"&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;Define a simple exception class and run the tests again. You'll see that &lt;code&gt;JuanitoMock::ExpectationNotSatisfied expected but nothing was raised.&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 27046

&lt;span class="c"&gt;# Running:&lt;/span&gt;

...F

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001435s, 2788.1462 runs/s, 2788.1462 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Failure:
JuanitoMock#test_0004_expects that a message will be received &lt;span class="o"&gt;[&lt;/span&gt;/Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:39]:
JuanitoMock::ExpectationNotSatisfied expected but nothing was raised.

4 runs, 4 assertions, 1 failures, 0 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's expected. We merely created the &lt;code&gt;ExpectationTarget&lt;/code&gt; and &lt;code&gt;ExpectationNotSatisfied&lt;/code&gt; classes, and we have not added anything new to the &lt;code&gt;Stubber.reset&lt;/code&gt; method, so it's right that the new test is failing.&lt;/p&gt;

&lt;p&gt;What should &lt;code&gt;Stubber.reset&lt;/code&gt; do that would make our test pass? Hmm.. &lt;code&gt;Stubber.reset&lt;/code&gt; should be checking that all of our expectations are verified, and would raise an error if any of the expectations failed. Why don't we add a &lt;code&gt;verify&lt;/code&gt; method to each &lt;code&gt;Stubber&lt;/code&gt; instance that would do the checking?&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;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;TestExtensions&lt;/span&gt;
    &lt;span class="o"&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;reset&lt;/span&gt;
    &lt;span class="n"&gt;expectations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:verify&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;Stubber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&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;expectations&lt;/span&gt;
    &lt;span class="vi"&gt;@expectations&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works, but if an exceptation is raised when &lt;code&gt;verify&lt;/code&gt; fails, then &lt;code&gt;Stubber.reset&lt;/code&gt; would not actually be executed because the exception would have broke the control flow.&lt;/p&gt;

&lt;p&gt;We want to make sure that &lt;code&gt;Stubber.reset&lt;/code&gt; is called even if any expectation raised an exception, and we also want to clear &lt;code&gt;@expectations&lt;/code&gt; too so that weird things won't happen. Ruby's &lt;code&gt;ensure&lt;/code&gt; is here to help:&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;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;TestExtensions&lt;/span&gt;
    &lt;span class="o"&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;reset&lt;/span&gt;
    &lt;span class="n"&gt;expectations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:verify&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;ensure&lt;/span&gt;
    &lt;span class="n"&gt;expectations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;
    &lt;span class="no"&gt;Stubber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="o"&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;Run the tests again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 12211

&lt;span class="c"&gt;# Running:&lt;/span&gt;

...F

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001460s, 2738.9588 runs/s, 2738.9588 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Failure:
JuanitoMock#test_0004_expects that a message will be received &lt;span class="o"&gt;[&lt;/span&gt;/Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:39]:
&lt;span class="o"&gt;[&lt;/span&gt;JuanitoMock::ExpectationNotSatisfied] exception expected, not
Class: &amp;lt;NoMethodError&amp;gt;
Message: &amp;lt;&lt;span class="s2"&gt;"undefined method &lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;verify&lt;span class="s1"&gt;' for #&amp;lt;JuanitoMock::ExpectationDefinition:0x007f89bb4b9640&amp;gt;"&amp;gt;
---Backtrace---
/Users/Juan/null/juanito_mock/lib/juanito_mock.rb:97:in `each'&lt;/span&gt;
/Users/Juan/null/juanito_mock/lib/juanito_mock.rb:97:in &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="s2"&gt;reset'
/Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:40:in &lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="o"&gt;(&lt;/span&gt;3 levels&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &amp;lt;top &lt;span class="o"&gt;(&lt;/span&gt;required&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'
---------------

4 runs, 4 assertions, 1 failures, 0 errors, 0 skips

rake aborted!
Command failed with status (1): [ruby -I"lib:test:lib"  "/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb" "test/juanito_mock_test.rb" ]

Tasks: TOP =&amp;gt; default =&amp;gt; test
(See full trace by running task with --trace)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Getting there! We have an undefined method &lt;code&gt;verify&lt;/code&gt; on &lt;code&gt;ExpectationDefinition&lt;/code&gt;. Let's do the simplest thing to make the test pass! We'll define the &lt;code&gt;verify&lt;/code&gt; method and just raise &lt;code&gt;ExpectationNotSatisfied&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExpectationDefinition&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;return_value&lt;/span&gt;
      &lt;span class="nb"&gt;self&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;verify&lt;/span&gt;
      &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="no"&gt;ExpectationNotSatisfied&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="o"&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;Run the tests! All green!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 22996

&lt;span class="c"&gt;# Running:&lt;/span&gt;

....

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001272s, 3143.7915 runs/s, 3143.7915 assertions/s.

4 runs, 4 assertions, 0 failures, 0 errors, 0 skips
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this is clearly not right even though we have all passing tests. We have a gap in our testing and we'll expose that gap by writing a new test:&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;it&lt;/span&gt; &lt;span class="s2"&gt;"does not raise an error if expectations are satisfied"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;warehouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&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;assume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:empty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty&lt;/span&gt;

    &lt;span class="no"&gt;JuanitoMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt; &lt;span class="c1"&gt;# assert nothing raised!&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run the tests again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 46019

&lt;span class="c"&gt;# Running:&lt;/span&gt;

E....

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001292s, 3870.3166 runs/s, 3096.2532 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0005_does not raise an error &lt;span class="k"&gt;if &lt;/span&gt;expectations are satisfied:
JuanitoMock::ExpectationNotSatisfied: JuanitoMock::ExpectationNotSatisfied
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:82:in &lt;span class="sb"&gt;`&lt;/span&gt;verify&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:101:in `each'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:101:in &lt;span class="sb"&gt;`&lt;/span&gt;reset&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:51:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

5 runs, 4 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The new test is failing now because &lt;code&gt;verify&lt;/code&gt; always raises an exception! That's our cue to implement the actual logic for the &lt;code&gt;verify&lt;/code&gt; method which checks if a method has been invoked.&lt;/p&gt;

&lt;p&gt;Again, a simple way to solve this would be to use an invocation count as verification, like so:&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;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExpectationDefinition&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;
      &lt;span class="vi"&gt;@invocation_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verify&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@invocation_count&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="no"&gt;ExpectationNotSatisfied&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="o"&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;But we don't really have a way to increment invocation count. Maybe...&lt;/p&gt;

&lt;p&gt;Let's look at the following in &lt;code&gt;Stubber#stub&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;return_value&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 we define the singleton method, we are just simply returning the value via &lt;code&gt;definition.return_value&lt;/code&gt;. Instead, let's modify it to look like:&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="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Invoking a &lt;code&gt;call&lt;/code&gt; method is a standard practice if you want an object to act like a callable piece of code, like a &lt;code&gt;proc&lt;/code&gt; or &lt;code&gt;lambda&lt;/code&gt; (which also has the &lt;code&gt;call&lt;/code&gt; method).&lt;/p&gt;

&lt;p&gt;Let's run the tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 56524

&lt;span class="c"&gt;# Running:&lt;/span&gt;

.E..E

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001311s, 3815.1804 runs/s, 2289.1082 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0001_allows an object to receive a message and returns a value:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;call&lt;span class="s1"&gt;' for #&amp;lt;JuanitoMock::ExpectationDefinition:0x007fa065d1a030&amp;gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:52:in `block in stub'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="o"&gt;(&lt;/span&gt;2 levels&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &amp;lt;top &lt;span class="o"&gt;(&lt;/span&gt;required&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'


  2) Error:
JuanitoMock#test_0005_does not raise an error if expectations are satisfied:
NoMethodError: undefined method `call'&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="c"&gt;#&amp;lt;JuanitoMock::ExpectationDefinition:0x007fa065d18b40&amp;gt;&lt;/span&gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:52:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="k"&gt;in &lt;/span&gt;stub&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:49:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

5 runs, 3 assertions, 0 failures, 2 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's add the method &lt;code&gt;call&lt;/code&gt; for &lt;code&gt;ExpectationDefinition&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExpectationDefinition&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;
      &lt;span class="vi"&gt;@invocation_count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="vi"&gt;@return_value&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;verify&lt;/span&gt;
      &lt;span class="o"&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="o"&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;The &lt;code&gt;call&lt;/code&gt; method will still return the &lt;code&gt;return_value&lt;/code&gt; (as was happening earlier with &lt;code&gt;definition.return_value&lt;/code&gt;), but at the same time, it also increases the &lt;code&gt;@invocation_count&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now run the tests again, and we would be all green again!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 47647

&lt;span class="c"&gt;# Running:&lt;/span&gt;

.....

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001300s, 3846.9144 runs/s, 3077.5315 assertions/s.

5 runs, 4 assertions, 0 failures, 0 errors, 0 skips
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! We now have basic stub and mock functionality for &lt;code&gt;JuanitoMock&lt;/code&gt;. But we don't have yet the ability to pass (and expect) arguments to stubs.&lt;/p&gt;

&lt;p&gt;Let's write a test for that:&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;it&lt;/span&gt; &lt;span class="s2"&gt;"allows object to receive messages with arguments"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;warehouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&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;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&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="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&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="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9876&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;must_equal&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9876&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;must_equal&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run the tests to see what should we do next:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 17857

&lt;span class="c"&gt;# Running:&lt;/span&gt;

E.....

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001458s, 4116.0535 runs/s, 2744.0357 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0006_allows object to receive messages with arguments:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;with&lt;span class="s1"&gt;' for #&amp;lt;JuanitoMock::ExpectationDefinition:0x007fb1f2d010f0&amp;gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:57:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

6 runs, 4 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We don't have the &lt;code&gt;with&lt;/code&gt; on &lt;code&gt;ExpectationDefinition&lt;/code&gt;. Let's do it:&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;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExpectationDefinition&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;and_return&lt;/span&gt;
      &lt;span class="o"&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;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@arguments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;
      &lt;span class="nb"&gt;self&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

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

  &lt;span class="o"&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;The &lt;code&gt;with&lt;/code&gt; method will accept an array of arguments, made possible using the splat operator (&lt;code&gt;*&lt;/code&gt;), and we also return &lt;code&gt;self&lt;/code&gt; to make it chainable.&lt;/p&gt;

&lt;p&gt;Run the tests again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 16039

&lt;span class="c"&gt;# Running:&lt;/span&gt;

...E..

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001207s, 4969.8536 runs/s, 3313.2358 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0006_allows object to receive messages with arguments:
ArgumentError: wrong number of arguments &lt;span class="o"&gt;(&lt;/span&gt;1 &lt;span class="k"&gt;for &lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:51:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="k"&gt;in &lt;/span&gt;stub&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:60:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

6 runs, 4 assertions, 0 failures, 1 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we see &lt;code&gt;ArgumentError&lt;/code&gt;: &lt;code&gt;wrong number of arguments (1 for 0)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's decrypt this error message.&lt;/p&gt;

&lt;p&gt;What it's saying is that you passed in &lt;em&gt;1 argument&lt;/em&gt;, but the method defined only requires &lt;em&gt;0 arguments&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Luckily there is also a line number telling us where things went wrong:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lib/juanito_mock.rb:51:in `block in stub'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Line 51 or &lt;code&gt;Stubber#stub&lt;/code&gt; should be:&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="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's allow the &lt;code&gt;define_singleton_method&lt;/code&gt; block to accept splat arguments as well:&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="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&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;arguments&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the tests again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 3190

&lt;span class="c"&gt;# Running:&lt;/span&gt;

..F...

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001697s, 3536.4931 runs/s, 2947.0775 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Failure:
JuanitoMock#test_0006_allows object to receive messages with arguments &lt;span class="o"&gt;[&lt;/span&gt;/Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:60]:
Expected: &lt;span class="nb"&gt;true
  &lt;/span&gt;Actual: &lt;span class="nb"&gt;false

&lt;/span&gt;6 runs, 5 assertions, 1 failures, 0 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we now have a failure on our test:&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;warehouse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;must_equal&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
  &lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9876&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;must_equal&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's look at the test again:&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;it&lt;/span&gt; &lt;span class="s2"&gt;"allows object to receive messages with arguments"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;warehouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&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;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&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="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&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="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9876&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;must_equal&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
  &lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9876&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;must_equal&lt;/span&gt; &lt;span class="kp"&gt;false&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;code&gt;warehouse.include?(1234)&lt;/code&gt; is returning false (and failing the test). That's because we have yet to do any matching on the stub argument and so the last stub&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;allow(warehouse).to receive(:include?).with(9876).and_return(false)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is the one that's being returned, no matter what arguments are used.&lt;/p&gt;

&lt;p&gt;Why is the last stub returned? Remember when we defined the singleton 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="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&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;arguments&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We only invoked a definition via &lt;code&gt;definition.call&lt;/code&gt;, but we didn't actually invoke &lt;em&gt;the right definition&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Similar to our &lt;code&gt;reset&lt;/code&gt; method, we should (&lt;a href="http://ruby-doc.org/core-2.2.2/Array.html#method-i-reverse"&gt;&lt;code&gt;reverse&lt;/code&gt;&lt;/a&gt;) search and &lt;a href="http://ruby-doc.org/core-2.2.2/Enumerable.html#method-i-find"&gt;&lt;code&gt;find&lt;/code&gt;&lt;/a&gt; the definition that matches the method name and arguments:&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="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&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;arguments&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="vi"&gt;@definitions&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reverse&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the tests again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 61311

&lt;span class="c"&gt;# Running:&lt;/span&gt;

E.EEE.

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001315s, 4563.6538 runs/s, 1521.2179 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0001_allows an object to receive a message and returns a value:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;reverse&lt;span class="s1"&gt;' for nil:NilClass
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:54:in `block in stub'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="o"&gt;(&lt;/span&gt;2 levels&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &amp;lt;top &lt;span class="o"&gt;(&lt;/span&gt;required&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'


  2) Error:
JuanitoMock#test_0005_does not raise an error if expectations are satisfied:
NoMethodError: undefined method `reverse'&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;nil:NilClass
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:54:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="k"&gt;in &lt;/span&gt;stub&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:49:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;


  3&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0003_preserves methods that are originally existed:
JuanitoMock::ExpectationNotSatisfied: JuanitoMock::ExpectationNotSatisfied
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:97:in &lt;span class="sb"&gt;`&lt;/span&gt;verify&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:117:in `each'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:117:in &lt;span class="sb"&gt;`&lt;/span&gt;reset&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:27:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;


  4&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0006_allows object to receive messages with arguments:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;reverse&lt;span class="s1"&gt;' for nil:NilClass
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:54:in `block in stub'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:60:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="o"&gt;(&lt;/span&gt;2 levels&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &amp;lt;top &lt;span class="o"&gt;(&lt;/span&gt;required&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'

6 runs, 2 assertions, 0 failures, 4 errors, 0 skips

rake aborted!
Command failed with status (1): [ruby -I"lib:test:lib"  "/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb" "test/juanito_mock_test.rb" ]

Tasks: TOP =&amp;gt; default =&amp;gt; test
(See full trace by running task with --trace)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yikes. 4 tests failed! Let's take a look at the last one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;JuanitoMock#test_0006_allows object to receive messages with arguments:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;reverse&lt;span class="s1"&gt;' for nil:NilClass
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:54:in `block in stub'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:60:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="o"&gt;(&lt;/span&gt;2 levels&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &amp;lt;top &lt;span class="o"&gt;(&lt;/span&gt;required&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hmm. Let's look at our implementation again:&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="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&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;arguments&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="vi"&gt;@definitions&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reverse&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why is &lt;code&gt;@definitions&lt;/code&gt; &lt;code&gt;nil&lt;/code&gt;? That's because &lt;code&gt;self&lt;/code&gt; has changed, in a singleton method block like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&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;arguments&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&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;And because instance variables (&lt;code&gt;@definitions&lt;/code&gt;) are looked up on &lt;code&gt;self&lt;/code&gt; (which is now &lt;code&gt;@obj&lt;/code&gt; and not the outer instance), &lt;code&gt;@definitions&lt;/code&gt; is something different (and unintialized) in the block. We call this a closure.&lt;/p&gt;

&lt;p&gt;An easy fix would be to create a temporary variable:&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;module&lt;/span&gt; &lt;span class="nn"&gt;JuanitoMock&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stubber&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;

      &lt;span class="n"&gt;definitions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@definitions&lt;/span&gt;
      &lt;span class="vi"&gt;@obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&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;arguments&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;definitions&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reverse&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reset&lt;/span&gt;
      &lt;span class="o"&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="o"&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;Run the tests again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 52635

&lt;span class="c"&gt;# Running:&lt;/span&gt;

..EEEE

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001867s, 3214.3833 runs/s, 1071.4611 assertions/s.

  1&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0006_allows object to receive messages with arguments:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;matches&lt;span class="s1"&gt;' for #&amp;lt;JuanitoMock::ExpectationDefinition:0x007ff542c9bf00&amp;gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:55:in `block (2 levels) in stub'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:55:in &lt;span class="sb"&gt;`&lt;/span&gt;each&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:55:in `find'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:55:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="k"&gt;in &lt;/span&gt;stub&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:60:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;


  2&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0005_does not raise an error &lt;span class="k"&gt;if &lt;/span&gt;expectations are satisfied:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;matches&lt;span class="s1"&gt;' for #&amp;lt;JuanitoMock::ExpectationDefinition:0x007ff542c9b7d0&amp;gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:55:in `block (2 levels) in stub'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:55:in &lt;span class="sb"&gt;`&lt;/span&gt;each&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:55:in `find'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:55:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="k"&gt;in &lt;/span&gt;stub&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:49:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;


  3&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0003_preserves methods that are originally existed:
JuanitoMock::ExpectationNotSatisfied: JuanitoMock::ExpectationNotSatisfied
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:98:in &lt;span class="sb"&gt;`&lt;/span&gt;verify&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:118:in `each'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:118:in &lt;span class="sb"&gt;`&lt;/span&gt;reset&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:27:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;


  4&lt;span class="o"&gt;)&lt;/span&gt; Error:
JuanitoMock#test_0001_allows an object to receive a message and returns a value:
NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;matches&lt;span class="s1"&gt;' for #&amp;lt;JuanitoMock::ExpectationDefinition:0x007ff542c9ad30&amp;gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:55:in `block (2 levels) in stub'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:55:in &lt;span class="sb"&gt;`&lt;/span&gt;each&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:55:in `find'&lt;/span&gt;
    /Users/Juan/null/juanito_mock/lib/juanito_mock.rb:55:in &lt;span class="sb"&gt;`&lt;/span&gt;block &lt;span class="k"&gt;in &lt;/span&gt;stub&lt;span class="s1"&gt;'
    /Users/Juan/null/juanito_mock/test/juanito_mock_test.rb:9:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

6 runs, 2 assertions, 0 failures, 4 errors, 0 skips

rake aborted!
Command failed with status &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ruby &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="s2"&gt;"lib:test:lib"&lt;/span&gt;  &lt;span class="s2"&gt;"/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/rake_test_loader.rb"&lt;/span&gt; &lt;span class="s2"&gt;"test/juanito_mock_test.rb"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

Tasks: TOP &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; default &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;See full trace by running task with &lt;span class="nt"&gt;--trace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We got rid of the &lt;code&gt;nil&lt;/code&gt; error, and now we have an undefined method &lt;code&gt;matches&lt;/code&gt; in &lt;code&gt;ExpectationDefinition&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;This is the final step, I promise:&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;ExpectationDefinition&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&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;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="vi"&gt;@message&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@arguments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="vi"&gt;@arguments&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="o"&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;Again, we'll run all the tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rake
Run options: &lt;span class="nt"&gt;--seed&lt;/span&gt; 14495

&lt;span class="c"&gt;# Running:&lt;/span&gt;

......

Finished &lt;span class="k"&gt;in &lt;/span&gt;0.001514s, 3963.4020 runs/s, 3963.4020 assertions/s.

6 runs, 6 assertions, 0 failures, 0 errors, 0 skips
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have ALL OUR TESTS PASSING!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C O N G R A T U L A T I O N S&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You've got a basic mocking library!&lt;/p&gt;

&lt;p&gt;This library is pretty good now, except with some caveats...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;with(...)&lt;/code&gt; and calling it with different arguments raises &lt;code&gt;NoMethodError&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;define_singleton_method&lt;/code&gt; and &lt;code&gt;singleton_class&lt;/code&gt; are on &lt;code&gt;Object&lt;/code&gt; and so stubbing on &lt;code&gt;BasicObject&lt;/code&gt; is not supported&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;private&lt;/code&gt; methods are not preserved&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;reset&lt;/code&gt;   method should be invoked automatically at the end of each test (&lt;code&gt;teardown&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Luckily, RSpec already addressed these and more, so you can just use &lt;a href="https://github.com/rspec/rspec-mocks"&gt;rspec-mocks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Further Reading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;allow/expect&lt;/code&gt; discussion in RSpec: &lt;a href="https://github.com/rspec/rspec-mocks/issues/153"&gt;https://github.com/rspec/rspec-mocks/issues/153&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The work from this tutorial: &lt;a href="https://github.com/JuanitoFatas/juanito_mock"&gt;juanito_mock&lt;/a&gt;, original code &lt;a href="https://github.com/alindeman/ancient_mock/"&gt;ancient_mock&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.google.com/presentation/d/1laaQYHFyzcTJzlB9qMmEHyoHIB-S93p9B4L8SbbhoTw/edit#slide=id.p"&gt;Building a Mocking Library Slides&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Happy Mocking!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Till next time 😘&lt;br&gt;
&lt;em&gt;Juanito Fatas&lt;/em&gt;,&lt;br&gt;
&lt;em&gt;Edits by Winston Teo Yong Wei&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you tweet or share this tutorial, don't forget to mention and thank &lt;a class="comment-mentioned-user" href="https://dev.to/alindeman"&gt;@alindeman&lt;/a&gt;
!&lt;/p&gt;

&lt;p&gt;All credits go to him! I only did the writing here. 😉&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://juanitofatas.com/mocking_in_ruby"&gt;juanitofatas.com&lt;/a&gt; on August 20th, 2015.&lt;/em&gt;&lt;/p&gt;

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