# Separate code space/sandbox?

**URL:** <https://www.ruby-forum.com/t/separate-code-space-sandbox/178820>\
**Category:** Ruby\
**Created:** [November 11, 2009, 7:51pm UTC](https://www.ruby-forum.com/t/separate-code-space-sandbox/178820 "2009-11-11T19:51:33Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![patrik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/e9bcb4/32.png) [@patrik](https://www.ruby-forum.com/u/patrik)\
**Post date:** [November 11, 2009, 7:51pm UTC](https://www.ruby-forum.com/t/separate-code-space-sandbox/178820/1 "2009-11-11T19:51:33Z")

</div>

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.

Is something like that already available? If not, any good ideas for  
how to implement it?

I did have a quick look at sandbox by \_why, seems may do what I want  
but not so keen on the interpreter patching etc so looking for  
opportunities.

Regards,  
Patrik

---

<div class="post-metadata">

**Author:** ![patrik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/e9bcb4/32.png) [@patrik](https://www.ruby-forum.com/u/patrik)\
**Post date:** [November 11, 2009, 9:48pm UTC](https://www.ruby-forum.com/t/separate-code-space-sandbox/178820/2 "2009-11-11T21:48:01Z")

</div>

From: “Patrik S.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> 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.

This isn’t very pretty, but…

class SeparatedScope  
def initialize(code)  
eval(code)  
end  
end

a = 10  
SeparatedScope.new %{  
a = 11  
p a  
}  
p a

…

Note there’s no access to outer scope variables at all in  
this case, thus the inner “a = 11” instead of “a = a + 1”.

☹

Regards,

Bill

---

<div class="post-metadata">

**Author:** ![patrik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/e9bcb4/32.png) [@patrik](https://www.ruby-forum.com/u/patrik)\
**Post date:** [November 12, 2009, 1:45pm UTC](https://www.ruby-forum.com/t/separate-code-space-sandbox/178820/3 "2009-11-12T13:45:06Z")

</div>

Bill K. wrote:

> Note there’s no access to outer scope variables at all in  
> this case, thus the inner “a = 11” instead of “a = a + 1”.
> 
> ☹

yeah, that doesn’t quite fly for my purpose - i want an initialization  
from current scope, then no impact on the parent scope.

---

<div class="post-metadata">

**Author:** ![patrik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/e9bcb4/32.png) [@patrik](https://www.ruby-forum.com/u/patrik)\
**Post date:** [November 12, 2009, 8:38pm UTC](https://www.ruby-forum.com/t/separate-code-space-sandbox/178820/4 "2009-11-12T20:38:06Z")

</div>

Caleb C. wrote:

> 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 [GitHub - coatl/rubymacros: RubyMacros is a lisp-like macro pre-processor for Ruby. More than just a purely textual substitution scheme, RubyMacros can manipulate and morph Ruby parse trees (in the form of RedParse Nodes) at parse time in just about any way you see fit.](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.

Awesome! I had not seen rubymacros before. I’ll dig into this and try to  
understand it in more detail.

Thank you very much for the help.

---

<div class="post-metadata">

**Author:** ![patrik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/e9bcb4/32.png) [@patrik](https://www.ruby-forum.com/u/patrik)\
**Post date:** [November 12, 2009, 8:35pm UTC](https://www.ruby-forum.com/t/separate-code-space-sandbox/178820/5 "2009-11-12T20:35:23Z")

</div>

On 11/11/09, Patrik S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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 [GitHub - coatl/rubymacros: RubyMacros is a lisp-like macro pre-processor for Ruby. More than just a purely textual substitution scheme, RubyMacros can manipulate and morph Ruby parse trees (in the form of RedParse Nodes) at parse time in just about any way you see fit.](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.

---

<div class="post-metadata">

**Author:** ![patrik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/e9bcb4/32.png) [@patrik](https://www.ruby-forum.com/u/patrik)\
**Post date:** [November 12, 2009, 9:24pm UTC](https://www.ruby-forum.com/t/separate-code-space-sandbox/178820/6 "2009-11-12T21:24:35Z")

</div>

> If you get stuck or can’t understand something, don’t hesitate to ask  
> me.

Sweet I want to use macros. How about one to support ++? 🙂  
-r

---

<div class="post-metadata">

**Author:** ![patrik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/e9bcb4/32.png) [@patrik](https://www.ruby-forum.com/u/patrik)\
**Post date:** [November 12, 2009, 9:00pm UTC](https://www.ruby-forum.com/t/separate-code-space-sandbox/178820/7 "2009-11-12T21:00:34Z")

</div>

On 11/12/09, Patrik S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Awesome! I had not seen rubymacros before. I’ll dig into this and try to  
> understand it in more detail.

If you get stuck or can’t understand something, don’t hesitate to ask  
me.

---

<div class="post-metadata">

**Author:** ![patrik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/e9bcb4/32.png) [@patrik](https://www.ruby-forum.com/u/patrik)\
**Post date:** [November 12, 2009, 11:39pm UTC](https://www.ruby-forum.com/t/separate-code-space-sandbox/178820/8 "2009-11-12T23:39:47Z")

</div>

On 11/12/09, Roger P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > If you get stuck or can’t understand something, don’t hesitate to ask  
> > me.
> 
> Sweet I want to use macros. How about one to support ++

Hmm, I had thought that ruby’s immutable numeric types meant this was  
impossible, but maybe it is feasible to implement as a macro… (not  
as a method).

The big problem is that I haven’t (uh, yet) written the magic that  
will allow users to define their own operators. (Or (re)define  
existing operators as macros…)

But other than that, this ought to be possible… you’d need to use  
different names until operator macros are defined, tho.  
The preincrement version could be written like this:

macro preincr(n)  
☹ ^n+=1 )  
end

postincrement is somewhat more difficult. Here’s a first pass:

macro postincr(n)  
☹ (res=^n;^n+=1;res) )  
end

(Warning: both increment macros are untested.)

but postincr is problematic. A call like:  
postincr( a().b )  
would cause a().b to be evaluated twice, which isn’t right. Solving  
this, so that side effects in the arg to postincr are evaluated only  
once, is more complicated, and I won’t attempt it here.

And nobody wants to type preincr or postincr (or even incr) when they  
could just use +=1, so we’d really need user-defined operators  
here…

> ? 🙂

Is that a self-portrait? 😉
