3

I'm writing a DSL for a project and I've run into an issue involving local variables bleeding into nested procs when I don't want them to. It seems like no matter what I try, I can't overwrite a local variable's value with something from another scope once it's been set into a proc's binding.

an example of what I'm trying to get to work:

class Obj
  def foo
    :foo
  end
end

def run_proc(context, &block)
  context.instance_exec(&block)
end

def run_example(context)
  # This `foo` the local var that ends up in the binding of
  # the proc on the next line that I can't seem to overwrite
  foo = :bar   
  run_proc(context) { foo }
  # ^ I want to be able to eval `foo` based on the passed context obj
end

obj = Obj.new
# I want all three of these calls to return `:foo`
obj.foo                   #=> :foo  # works as expected
obj.instance_exec { foo } #=> :foo  # works as expected
run_example(obj)          #=> :bar  # doesn't work, since the `run_example`
                                    #  method's local `foo` var takes precedence
                                    #  over the passed object's `foo` method

I did some digging around and found answers with a similar approach to what I've been trying: Change the binding of a Proc in Ruby. I've also looked into the possibility of undefining the local variables in a proc's binding but this answer claims doing so is impossible: Undefine variable in Ruby.

So my question now is this: Should I just give up trying to nest procs and/or find a workaround that doesn't have local var/method name conflict issues, or is there actually a way to get around this?

Nick deLannoy
  • 31
  • 1
  • 4

1 Answers1

2

You can use self.foo explicitely

Using it will call the bindings of the object self currently refers to rather then the closure of the state when proc/block is created.