The Thrilling Freaky-Freaky Sandbox Hack!!
Holy cats, I’m proud to offer you this sensational hack today. For me, this is monumental, as it culminates a number of sundry microhacks from the past few years and gets us a step closer to realizing Try Ruby out in the broader kingdoms. This is the sort of thing that will make you want to post spangly angel GIFs in the comments.
Okay, requires a compiler. Then:
gem install sandbox --source code.whytheluckystiff.net
Now, to create a sandboxed Ruby interp.
>> require 'rubygems' >> require 'sandbox' >> s = Sandbox.new => #<Sandbox:0x84dea60> >> s.eval("2 + 6") => 8 >> s.eval("'Jimmy'.reverse") => "ymmiJ" >> s.eval('"Jimmy".length') => 5
Okay, so you can do all the Try Ruby examples. And what about danger?
>> s.eval("Kernel.fork") (eval):1:in `method_missing': uninitialized constant NoMethodError::message (NameError)
Oh, check that out. Not only is
Kernel.fork not defined, but
NoMethodError isn’t defined either!
And yet, both are defined in the main interpreter outside the sandbox:
>> Kernel.method(:fork) => #<Method: Kernel.fork> >> NoMethodError => NoMethodError
There are some security holes still being worked out on Ruby-Core, I need a few variables exposed. But, it’s looking really good. Many thanks to MenTaLguY who helped conceive this idea here in the comments.
So what are the implications? Oh, come on!
- Load multiple Rails apps, Camping apps, Nitro apps into the same interpreter without polluting each other’s namespaces.
- Allow Ruby code from users of your application without danger of affecting the app itself. (Scriptable wikis, markaby templates, ohhhh so many uses.)
- Load several different versions of libraries at once (for testing and compatibility issues.)
- Reloading an app within itself. (Fathom.)
- Snapshoting an environment for reuse at a later stage. (The
sandkitstruct stores the whole environment.)
Eval has just become the least evil.
alias docile eval!