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
).
When using parameters prefixed with ampersands, passing a block to a method results in a proc in the method's context. Procs behave like blocks, but they can be stored in a variable. Lambdas are procs that behave like methods, meaning they enforce arity and return as methods instead of in their parent scope.
A Proc object is an encapsulation of a block of code, which can be stored in a local variable, passed to a method or another Proc, and can be called. Lambdas are anonymous functions, objects of the class Proc, they are useful in most of the situations where you would use a proc.
A ruby block is one or more lines of code that you put inside the do and end keywords (or { and } for inline blocks).
Ruby blocks are anonymous functions that can be passed into methods. Blocks are enclosed in a do-end statement or curly braces {}. do-end is usually used for blocks that span through multiple lines while {} is used for single line blocks. Blocks can have arguments which should be defined between two pipe | characters.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With