Manikandan
Manikandan

Reputation: 3165

Persist ruby binding

Is there any way to persist ruby bindings ? I couldn't use marshal.dump. Doc says

if the objects to be dumped include bindings, procedure or method objects, instances of class IO, or singleton objects, a TypeError will be raised.

We need to use same binding across multiple requests. How can I serialize/deserilaze ruby binding ?

Upvotes: 4

Views: 145

Answers (1)

philomory
philomory

Reputation: 1767

The idea of serializing a binding is in many ways incoherent, because a binding is intimately connected to the run-time stack; when you de-serialized the binding, should it re-create the stack, too?

That said, if you just want to get the values out of the binding, you could do it with something like this:

class Binding
  def values_for_serialization
    data = {
      locals: {},
      self: eval('self',self)
    }
    eval("local_variables",self).each do |lvar|
      data[:locals][lvar] = local_variable_get(lvar)
    end
    data
  end
end

You could then serialize the returned structure using Marshal#dump, to_yaml, or whatever.

De-serializing would work something like this:

class Binding
  def self.from_values(values)
    bind = values[:self].instance_exec { binding }
    values[:locals].each_pair do |lvar,value|
      bind.local_variable_set(lvar,value)
    end
    bind
   end
 end

But note that, while this would give you a binding that had an appropriate self object, and appropriate local variables, it wouldn't really be the same binding. For instance, if you tried to use this to serialize the top-level script binding, you could; and then in another script you could de-serialize it. But when you did, the local variables would not be available in that scripts top-level binding, they'd only be available in the binding object you'd created.

Upvotes: 1

Related Questions