GladstoneKeep GladstoneKeep - 4 months ago 9
Ruby Question

Executing code for every method call in a Ruby module

I'm writing a module in Ruby 1.9.2 that defines several methods. When any of these methods is called, I want each of them to execute a certain statement first.

module MyModule
def go_forth
a re-used statement
# code particular to this method follows ...
end

def and_multiply
a re-used statement
# then something completely different ...
end
end


But I want to avoid putting that
a re-used statement
code explicitly in every single method. Is there a way to do so?

(If it matters,
a re-used statement
will have each method, when called, print its own name. It will do so via some variant of
puts __method__
.)

Answer

Like this:

module M
  def self.before(*names)
    names.each do |name|
      m = instance_method(name)
      define_method(name) do |*args, &block|  
        yield
        m.bind(self).(*args, &block)
      end
    end
  end
end

module M
  def hello
    puts "yo"
  end

  def bye
    puts "bum"
  end

  before(*instance_methods) { puts "start" }
end

class C
  include M
end

C.new.bye #=> "start" "bum"
C.new.hello #=> "start" "yo"