Pass an object with the methods that you want to be available into the block as an argument. This is a pattern that's widely used in Ruby, such as in IO.open
or XML builder.
some_block do |thing|
thing.available_only_in_block
thing.is_this_here?
thing.okay_cool
end
Note that you can get closer to what you asked for using instance_eval
or instance_exec
, but that's generally a bad idea as it can have fairly surprising consequences.
class Foo
def bar
"Hello"
end
end
def with_foo &block
Foo.new.instance_exec &block
end
with_foo { bar } #=> "Hello"
bar = 10
with_foo { bar } #=> 10
with_foo { self.bar } #=> "Hello
While if you pass an argument in, you always know what you'll be referring to:
def with_foo
yield Foo.new
end
with_foo { |x| x.bar } #=> "Hello"
bar = 10
x = 20
with_foo { |x| x.bar } #=> "Hello"