I'm asking this question here because it occurred to me that RSpec seems to do what I want, but I can't figure out how to replicate this effect in my own code.
Inside the body of a class, I'd like to pass a block to a method called `with`. For the lifetime of the block, I would like a `with_value` method to be available. Otherwise, everything inside the block should behave as if it were outside the block.
Here's an example:
class C
extend M
with "some value" do
do_something_complicated
do_something_complicated
do_something_complicated
end
end
We can _almost_ get this with:
module M
def with(str, &block)
Object.new.tap do |wrapper|
wrapper.define_singleton_method :with_value do # Here's our with_value
str # method.
end
end.instance_eval &block
end
def do_something_complicated # Push a value onto an
(@foo ||= []).push with_value # array.
end
end
but there's a problem: since we're evaluating the block passed to `with` inside the context of a different object, `do_something_complicated` isn't available.
What's the right way to pull this off? Any suggestions?