Louis Kottmann
Louis Kottmann

Reputation: 16628

Clear a method's body

In order to handle a -q (quiet) option in my script, I did this:

class NoWrite
  def write(*args)
  end
end
$stdout = NoWrite.new if $options[:quiet]

It works fine.
However I'm wondering if there isn't a metaprogramming way of making the write method moot.

remove_method and undef_method can't be used because the write method has to be defined, I just want to make it do nothing.

Also, $stderr can't be impacted.

Upvotes: 1

Views: 73

Answers (2)

PinnyM
PinnyM

Reputation: 35531

You can use instance_eval for this:

$stdout.instance_eval{ def write(*args); end } if $options[:quiet]

Or you can make an anonymous class:

$stdout = Class.new{ def self.write(*args); end } if $options[:quiet]

Upvotes: 2

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230386

Alternatively, you can redirect stdout to /dev/null

def stfu
  begin
    orig_stdout = $stdout.clone
    $stdout.reopen File.new('/dev/null', 'w')
    retval = yield
  rescue Exception => e
    $stdout.reopen orig_stdout
    raise e
  ensure
    $stdout.reopen orig_stdout
  end
  retval
end

require 'some_noisy_gem'
stfu do
  some_function_that_generates_a_lot_of_cruft_on_stdout
end

Original snippet is at: https://jacob.hoffman-andrews.com/README/index.php/2011/04/14/ruby-function-stfu-temporarily-redirect-noisy-stdout-writes-to-devnull/

Upvotes: 3

Related Questions