Ruby: forward receiver, arguments and block across procs

Viewed 243

Given code like this:

p = proc do |*args, &block|
  p self
  p args
  p block[] if block
end

q = proc do |*args, &block|
  p 'before'
  instance_exec(*args, &p)
end

o = Object.new
o.define_singleton_method(:my_meth, q)
o.my_meth(1, 2) { 3 }

How can I completely forward the call from p to q while keeping q's receiver? Basically I want 3 printed as well, but instance_exec, like all ruby methods, can take only one block. Is it possible without changing p, so that I can use p and q interchangeably (the idea is to make q sometimes wrap p).

1 Answers

It is possible defining another singleton method:

p = proc do |*args, &block|
  p self
  p args
  p block[] if block
end

q = proc do |*args, &block|
  p 'before'
  define_singleton_method(:pp, p)
  pp(*args, &block)
end

o = Object.new
o.define_singleton_method(:my_meth, q)
o.my_meth(1, 2) { 3 }

Output:

"before"
#<Object:0x007f5903c2de28>
[1, 2]
3
=> 3
Related