# Restore Kernel.binding to a previous state

**URL:** <https://www.ruby-forum.com/t/restore-kernel-binding-to-a-previous-state/86474>\
**Category:** Ruby\
**Created:** [February 22, 2007, 4:15pm UTC](https://www.ruby-forum.com/t/restore-kernel-binding-to-a-previous-state/86474 "2007-02-22T16:15:53Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Hans\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ee59a6/32.png) [@Hans\_S](https://www.ruby-forum.com/u/Hans_S)\
**Post date:** [February 22, 2007, 4:15pm UTC](https://www.ruby-forum.com/t/restore-kernel-binding-to-a-previous-state/86474/1 "2007-02-22T16:15:53Z")

</div>

Hey all,

I’m implementing a simple queue system with which I’m evaling ‘jobs’,  
like so:

code = lambda {eval(job)}  
code.call

Where ‘job’ is a string containing ruby code.  
The problem I’m having is that I need these jobs to evaluate in a  
clean environment, uncluttered by the previous jobs. What I’d like is  
something along the lines of this:

temp = Kernel.binding  
code = lambda {eval(job)}  
code.call  
Kernel.binding = temp

Though that looks sort of dangerous.  
Another idea might be to be able to create a binding which is a deep  
copy of the current binding. I’m not sure if this has been done before.

---

<div class="post-metadata">

**Author:** ![Hans\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ee59a6/32.png) [@Hans\_S](https://www.ruby-forum.com/u/Hans_S)\
**Post date:** [February 22, 2007, 4:39pm UTC](https://www.ruby-forum.com/t/restore-kernel-binding-to-a-previous-state/86474/2 "2007-02-22T16:39:57Z")

</div>

On Fri, 23 Feb 2007, Hans S. wrote:

> clean environment, uncluttered by the previous jobs. What I’d like is

[http://www.linuxjournal.com/article/7922](http://www.linuxjournal.com/article/7922)  
[http://codeforpeople.com/lib/ruby/rq/](http://codeforpeople.com/lib/ruby/rq/)

if you’re on windows you’re out of luck though. in any case, all you  
need is  
a closure defined early on in your program. from there you evaluate the  
code.  
for example

harp:~ \> cat a.rb  
require ‘thread’

jq = SizedQueue.new 1  
rq = SizedQueue.new 1

runner = Thread.new do  
loop do  
job = jq.pop

```
 rq.push Thread.new{
   $SAFE = 4
   begin
     eval job
   rescue Exception => e
     e
   end
 }.value

```

end  
end

x = 42

jq.push ‘x = 42.0; x’  
p rq.pop

jq.push ‘x = :forty\_two; x’  
p rq.pop

harp:~ \> ruby a.rb  
42.0  
:forty\_two

basically you set of a thread server which, itself, is a thread. the  
top  
level thread is a closure of the initial context, so each new thread  
only has  
access to that clean environment. this does not reset the environment,  
but it  
does run each job in a clean one without poluting the current one.

regards.

-a

---

<div class="post-metadata">

**Author:** ![Hans\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ee59a6/32.png) [@Hans\_S](https://www.ruby-forum.com/u/Hans_S)\
**Post date:** [February 22, 2007, 5:02pm UTC](https://www.ruby-forum.com/t/restore-kernel-binding-to-a-previous-state/86474/3 "2007-02-22T17:02:09Z")

</div>

On Fri, Feb 23, 2007, Hans S. wrote:

> Where ‘job’ is a string containing ruby code.  
> The problem I’m having is that I need these jobs to evaluate in a  
> clean environment, uncluttered by the previous jobs. What I’d like is  
> something along the lines of this:
> 
> temp = Kernel.binding  
> code = lambda {eval(job)}  
> code.call  
> Kernel.binding = temp

I have (what I believe to be) a similar problem in some code I’m working  
on. It allows plugins written by the user to be executed, but each time  
it needs a clean environment. I’m taking advantage of the fact that you  
can pass eval a binding in which to execute. I have a simple binding  
factory which just creates new instances of itself and returns their  
binding:

class BindingFactory  
def self::get\_binding  
return self.new.send( :binding )  
end  
end

eval( action, BindingFactory.get\_binding )

For my purposes, it works like a charm:

> > ex1 = “a = :sym”  
> > =\> “a = :sym”
> 
> > ex2 = “puts a”  
> > =\> “puts a”
> 
> > eval ex1, BindingFactory.get\_binding  
> > =\> :sym
> 
> > eval ex2, BindingFactory.get\_binding  
> > NameError: undefined local variable or method `a' for #<BindingFactory:0x406f60f4> from (irb):18:in`send’  
> > from (irb):18:in `get\_binding’  
> > from (irb):24  
> > from :0

Is that helpful?

Ben

---

<div class="post-metadata">

**Author:** ![Hans\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ee59a6/32.png) [@Hans\_S](https://www.ruby-forum.com/u/Hans_S)\
**Post date:** [February 22, 2007, 8:41pm UTC](https://www.ruby-forum.com/t/restore-kernel-binding-to-a-previous-state/86474/4 "2007-02-22T20:41:40Z")

</div>

On Feb 22, 5:01 pm, Ben B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> end
> 
> > > eval ex1, BindingFactory.get\_binding
> 
> Ben

Helpful - yes, in finding out that using eval might not be what I’m  
after.  
I thought, at first, that a binding housed the entirety of a running  
ruby process’ context.

I’m wanting to run ruby snippets like the below:

require ‘rake’  
default = task :default do

# do stuff

end  
default.invoke

But for my problem, I might be better off using Kernel::system, and  
invoking ruby in an external process, even though I’d really like my  
little code-snippet to be able to access, for instance, the Logger  
I’ve set up in my queue-system.  
I might get away with that by modifying your BindingFactory to pass  
objects into the created binding as local variables. But stuff like  
rake modify the running context in more ways than setting local  
variables.

---

<div class="post-metadata">

**Author:** ![Hans\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ee59a6/32.png) [@Hans\_S](https://www.ruby-forum.com/u/Hans_S)\
**Post date:** [February 22, 2007, 8:56pm UTC](https://www.ruby-forum.com/t/restore-kernel-binding-to-a-previous-state/86474/5 "2007-02-22T20:56:41Z")

</div>

On Fri, 23 Feb 2007, Hans S. wrote:

> default = task :default do  
> rake modify the running context in more ways than setting local  
> variables.

why don’t you fork?

-a

---

<div class="post-metadata">

**Author:** ![Hans\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ee59a6/32.png) [@Hans\_S](https://www.ruby-forum.com/u/Hans_S)\
**Post date:** [February 22, 2007, 9:12pm UTC](https://www.ruby-forum.com/t/restore-kernel-binding-to-a-previous-state/86474/6 "2007-02-22T21:12:44Z")

</div>

On Fri, Feb 23, 2007, Hans S. wrote:

> Helpful - yes, in finding out that using eval might not be what I’m  
> after. I thought, at first, that a binding housed the entirety of a  
> running ruby process’ context.

Sort of. It includes the context of wherever the binding was created.  
If you call binding in the top level of your script, you’ll get all of  
that context that you can execute inside of.

> I’m wanting to run ruby snippets like the below:
> 
> require ‘rake’  
> default = task :default do
> 
> # do stuff
> 
> end  
> default.invoke

That’s exactly what I’m doing 🙂

> But for my problem, I might be better off using Kernel::system, and  
> invoking ruby in an external process, even though I’d really like my  
> little code-snippet to be able to access, for instance, the Logger  
> I’ve set up in my queue-system.

You can pretty easily inject variables into your binding. As I looked  
at my code, I realized that I actually am not using the BindingFactory  
idea (it was a prototype that I ended up not sticking with).

Instead, I have a Workspace class. It’s got a method called #set\_value  
that takes a name and value and sets an instance variable and adds an  
attr\_reader inside the workspace’s eigenclass.

Then, the tasks that I’ve got (I call them Command in my code) know how  
to execute themselves inside a workspace, so I can just say

command.execute( workspace )

and it calls the proc inside that binding.

I’m working on getting my code released (gotta get the company to  
agree), and until then I can’t show too much, but I’m happy to talk  
about it more if it sounds similar enough to what you’re doing to help.

Ben

---

<div class="post-metadata">

**Author:** ![Hans\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ee59a6/32.png) [@Hans\_S](https://www.ruby-forum.com/u/Hans_S)\
**Post date:** [February 22, 2007, 10:40pm UTC](https://www.ruby-forum.com/t/restore-kernel-binding-to-a-previous-state/86474/7 "2007-02-22T22:40:55Z")

</div>

On Feb 22, 8:56 pm, removed\_email\_address@domain.invalid wrote:

> > require ‘rake’  
> > objects into the created binding as local variables. But stuff like  
> > rake modify the running context in more ways than setting local  
> > variables.
> 
> why don’t you fork?
> 
> ## -a
> 
> be kind whenever possible… it is always possible.
> 
> - the dalai lama

Actually, that works perfectly. I was under the impression that  
Kernel.fork wrapped native fork() and thus wasn’t portable. But it  
works well for what I need.

---

<div class="post-metadata">

**Author:** ![Hans\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ee59a6/32.png) [@Hans\_S](https://www.ruby-forum.com/u/Hans_S)\
**Post date:** [February 24, 2007, 10:20am UTC](https://www.ruby-forum.com/t/restore-kernel-binding-to-a-previous-state/86474/8 "2007-02-24T10:20:57Z")

</div>

> The problem I’m having is that I need these jobs to evaluate  
> in a clean environment, uncluttered by the previous jobs.

You could use an anonymous module to de\_inspect a string:

a = “[1, 2, 3, 4]”.de\_inspect

gegroet,  
Erik V. - [http://www.erikveen.dds.nl/](http://www.erikveen.dds.nl/)

* * *

class String  
def de\_inspect  
Thread.new do  
$SAFE = 4

```
   eval(self, Module.new.module_eval{binding})
 end.value

```

end  
end

class String  
def de\_inspect\_unsafe  
eval(self, Module.new.module\_eval{binding})  
end  
end

---

<div class="post-metadata">

**Author:** ![Hans\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ee59a6/32.png) [@Hans\_S](https://www.ruby-forum.com/u/Hans_S)\
**Post date:** [February 22, 2007, 11:10pm UTC](https://www.ruby-forum.com/t/restore-kernel-binding-to-a-previous-state/86474/9 "2007-02-22T23:10:03Z")

</div>

On Fri, 23 Feb 2007, Hans S. wrote:

> works well for what I need.

definitely not portable. then again, thread aren’t so much either  
unless one  
is **very** careful with io and other blocking ops.

regards.

-a
