From: ara.t.howard@... Date: 2007-02-23T00:38:46+09:00 Subject: Re: Restore Kernel.binding to a previous state On Fri, 23 Feb 2007, Hans Sjunnesson wrote: > 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. > http://www.linuxjournal.com/article/7922 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 -- be kind whenever possible... it is always possible. - the dalai lama