On 11/11/09, Patrik Sundberg <patrik.sundberg / gmail.com> wrote: > Hi, > > I'm interested in figuring out a way to get a separate scope. I do not > need any other traditional sandbox features, i.e. any code goes, I > just want code evaluated in the scope to no affect the parent scope > (at all). Example illustrating what I am after: > > a = 10 > SeparatedScope.new do > a = a + 1 > p a > end > p a > > yielding: > 11 > 10 > > I'd like it to have the same initialization/separation also for > instance variables and even global variables if possible. Here's a macro which seems to do the job. Comments follow. #file separated_scope_user.rb require 'rubygems' require 'macro' Macro.require 'example/separated_scope' #file separated_scope.rb macro separated_scope code=yield localnames=[] code.depthwalk{|parent,i,j,node| if RedParse::VarNode===node node.name<<'_' localnames<<node.name end } :( ^localnames.uniq.inject(:(nil)){|sum,lvar| RedParse::AssignNode[ RedParse::VarNode[lvar],'=',sum ] } eval local_variables.map{|lvar| lvar+"_="+lvar}.join(';') ^code ) end a = 10 separated_scope do a = a + 1 p a #=>11 end p a #=>10 Commentary: 1) This is considerably more complicated (=uglier) than Bill's attempt. There's even an eval lurking in there, which oughtn't be necessary when using macros. However, it does seem to fulfill all your requirements. 2) A more sophisticated variable renaming scheme may be required if you want your program to have variables which end with an underscore. 3) Use of eval inside a separated_scope will confuse things. Variables used in the eval arg will refer to the outer scope, not the separated scope. 4) Macros are not a standard part of ruby syntax; they require my macro preprocessor, rubymacros. do a 'gem install rubymacros' to get it. Also see http://github.com/coatl/rubymacros 5) Code that defines or uses macros must be pulled into the interpreter using a special version of require: Macro.require. That's why there's a separate file which requires 'macro', then calls Macro.require.