Search code examples
ruby

Any way to create a new, empty Binding in Ruby?


Is there any way to create a completely empty Binding object for use with eval?

According to the docs, only the Kernel#binding method can create new bindings. I tried something like this:

empty = binding

but then, that binding has empty itself among its local variables, along with any other local variables in the same scope assigned later in the code.

I discovered that the constant TOPLEVEL_BINDING is a binding which is empty, and which suffices for my immediate purposes. It might not always, though.

Is there any way to create a brand new, completely empty Binding?


Solution

  • An easy way would be to write a method that calls binding and nothing else:

    def empty_binding
      binding
    end
    

    Then:

    b = empty_binding
    b.local_variables
    # [ ]
    

    That binding will still have a self and access to whatever instance variables are available to that self. You could limit that with some chicanery:

    module Empty
      def self.binding
        super
      end
    end
    
    b = Empty.binding
    b.eval('puts local_variables.inspect')
    # [ ]
    b.eval('puts instance_variables.inspect')
    # [ ]
    b.eval('puts self.inspect')
    # Empty
    

    What works depends on what the goal is. A binding with no local variables is pretty easy, a binding with nothing at all probably isn't possible without hacking Ruby itself (although BasicObject might be useful to get a little closer to empty than a module).

    None of these things give you a jail to safely eval inside if that's what you're after.