I need a method that takes a block, and performs something similar to an around_each filter for every method within the block.
For instance:
def method_that_takes_block
(@threads ||= Array.new) << Thread.new {yield if block.given?}
end
method_that_takes_a_block do
method_one
method_two
method_three
end
In this instance I would like my method that takes a block to Thread each method within the block and pushes that thread to the @threads array. Essentially I’m just looking for a DRY way to wrap a thread around every method called within a block.
You can’t directly wrap a thread around each statement in the block body, if they can be arbitrary statements; there’s no way to get that sort of control over the execution of a block body in Ruby. If you can restrict what goes in the block body, you have some more flexibility.
If each of the statements you are executing is simply a method call, as you imply in your example, you can use
instance_execto execute that block on a proxy object, which usesmethod_missingto spawn a new thread and then forward the method call on to the real object (or do whatever wrapper you’re interested in; for the sake of example, I’ll just wrap with some print statements):And here’s how you can use it:
The previous follows the pattern that you gave in your question, but it’s less than ideal as only methods that are forwarded to the underlying object get wrapped:
You could instead just use
instance_execdirectly, and call the a wrapper method that takes a block, to get almost the same effect, though slightly less DRY as you need to call your wrapper method each time:And in use: