title: How to I temporarily override print and puts from a class?
body: <p>I'm working on a shell for my project. I want the <code>Shell</code> class to override all print functions while the shell is running, so I've done this:</p>
  
  <pre><code># WARNING: Blocks until the user exits.
  def start
    # Override Kernel print functions.
    master_print = Kernel.method :print
    master_puts = Kernel.method :puts
  
    Kernel.module_exec {
      define_method(:print) { |text = ""|
        self.send(:print_override, master_print, text)
      }
      define_method(:puts) { |text = ""|
        self.send(:puts_override, master_puts, text)
      }
      define_method(:puts_padded) { |text = ""|
        self.send(:puts_override, master_puts, "")
        self.send(:puts_override, master_puts, text)
        self.send(:puts_override, master_puts, "")
      }
    }
  
    # Readline loop and command parsing here...
  end
  </code></pre>
  
  <p>This works well as long as only the <code>Shell</code> class is outputting any text, but as soon as a command class tries to <code>puts</code> I get this:</p>
  
  <pre class="lang-none prettyprint-override"><code>NoMethodError: undefined method `puts_override' for #&lt;AddressKit::CLI::Interactiv
  e::Commands::LoadTable:0x000000027735b0&gt;
  </code></pre>
  
  <p>I thought that the print and puts blocks I wrote above would stay in this scope, not execute in which ever scope they happened to be called from. Is it possible to fix that?</p>
  
  <hr>
  
  <p><em>Bonus question:</em> How do I put the original print functions back? I had planned this:</p>
  
  <pre><code>Kernel.module_exec {
    define_method(:print, &amp;master_print)
    define_method(:puts, &amp;master_puts)
    undef_method(:puts_padded)
  }
  </code></pre>
  
  <p>But I haven't tried it yet, and I don't know if that will leave <code>Kernel</code> exactly as I found it.</p>