# Opinion: Scripting in a Ruby program

**URL:** <https://www.ruby-forum.com/t/opinion-scripting-in-a-ruby-program/175028>\
**Category:** Ruby\
**Created:** [September 6, 2009, 1:47pm UTC](https://www.ruby-forum.com/t/opinion-scripting-in-a-ruby-program/175028 "2009-09-06T13:47:45Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![puck6633](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/ecb155/32.png) [@puck6633](https://www.ruby-forum.com/u/puck6633)\
**Post date:** [September 6, 2009, 1:47pm UTC](https://www.ruby-forum.com/t/opinion-scripting-in-a-ruby-program/175028/1 "2009-09-06T13:47:45Z")

</div>

Hello all, I’m working on a small program – and learning to love Ruby  
all over again – but I’ve come across a small dilemma: What if you want  
to make a Ruby program that can be extended without modifying the  
original code? That is, a Ruby script that can itself be scripted.

What I’m thinking of is something that gives users the ability to do  
basic math, access explicitly allowed methods and properties and maybe  
even allow user defined variables available only to that script, while  
disallowing any other use of the parent Ruby script. Something that is  
to Ruby what Ruby, Perl and Python are to C/C++.

I considered loading chunks of Ruby script and using eval() in a safe  
context, and also considered creating a very simple interpreted  
scripting language in Ruby, but before I proceed with either option I  
would like to pose this question to fellow Ruby enthusiasts: How would  
you handle making a scriptable/extensible Ruby program like this?

---

<div class="post-metadata">

**Author:** ![puck6633](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/ecb155/32.png) [@puck6633](https://www.ruby-forum.com/u/puck6633)\
**Post date:** [September 6, 2009, 2:06pm UTC](https://www.ruby-forum.com/t/opinion-scripting-in-a-ruby-program/175028/2 "2009-09-06T14:06:48Z")

</div>

A small but important addendum: the scripting method should also include  
conditionals of some sort.

---

<div class="post-metadata">

**Author:** ![puck6633](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/ecb155/32.png) [@puck6633](https://www.ruby-forum.com/u/puck6633)\
**Post date:** [September 6, 2009, 3:00pm UTC](https://www.ruby-forum.com/t/opinion-scripting-in-a-ruby-program/175028/3 "2009-09-06T15:00:59Z")

</div>

On 06.09.2009 13:47, Tristan S. wrote:

> I considered loading chunks of Ruby script and using eval() in a safe  
> context, and also considered creating a very simple interpreted  
> scripting language in Ruby, but before I proceed with either option I  
> would like to pose this question to fellow Ruby enthusiasts: How would  
> you handle making a scriptable/extensible Ruby program like this?

It seems like you just create a bunch of documented (!) classes and let  
users decide how they will use them. You can even go as far as  
providing a full script where the user can provide a main class name and  
invoke a method on that instead of your library provided main class.

Generally in the Ruby world we tend to impose less restrictions on class  
and object usage. If someone abuses the code, then that’s their  
decision. If it does not work, well… You get the picture.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![puck6633](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/ecb155/32.png) [@puck6633](https://www.ruby-forum.com/u/puck6633)\
**Post date:** [September 6, 2009, 6:51pm UTC](https://www.ruby-forum.com/t/opinion-scripting-in-a-ruby-program/175028/4 "2009-09-06T18:51:35Z")

</div>

Tristan S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hello all, I’m working on a small program – and learning to love Ruby  
> all over again – but I’ve come across a small dilemma: What if you want  
> to make a Ruby program that can be extended without modifying the  
> original code? That is, a Ruby script that can itself be scripted.

Well, of course I could be misunderstanding the question, but isn’t that  
exactly what any Ruby-based Web framework is? What is Ruby on Rails, for  
instance, but a Ruby script that you do not modify directly, but which  
turns to you at predefined times and in predefined ways and says,  
“extend me here if you wish!” So it’s just a question of supplying  
“hooks” and documenting them: here’s when I’ll turn to you, and here’s  
what you do and where you put your code in order for me to find it. (I  
use Ruby on Rails as an example because it is well known, but in fact  
the example that occurred to me when you asked this question was my own  
RubyFrontier, a much smaller, simpler Web framework, because that is  
exactly its philosophy and architecture.) m.

---

<div class="post-metadata">

**Author:** ![puck6633](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/ecb155/32.png) [@puck6633](https://www.ruby-forum.com/u/puck6633)\
**Post date:** [September 7, 2009, 6:43am UTC](https://www.ruby-forum.com/t/opinion-scripting-in-a-ruby-program/175028/5 "2009-09-07T06:43:17Z")

</div>

On Sunday 06 September 2009 06:47:47 am Tristan S. wrote:

> Hello all, I’m working on a small program – and learning to love Ruby  
> all over again – but I’ve come across a small dilemma: What if you want  
> to make a Ruby program that can be extended without modifying the  
> original code? That is, a Ruby script that can itself be scripted.

Unless you have a problem with Ruby, the way to do this is generally to  
provide a framework. As others have pointed out, Rails is the obvious  
example.

Indeed, one of the things that keeps me interested in Ruby, even when I  
keep  
seeing other cool little languages like IO and Erlang, is how expressive  
it  
is, particularly how easy it is to create DSLs.

> What I’m thinking of is something that gives users the ability to do  
> basic math, access explicitly allowed methods and properties and maybe  
> even allow user defined variables available only to that script, while  
> disallowing any other use of the parent Ruby script. Something that is  
> to Ruby what Ruby, Perl and Python are to C/C++.

If you have a legitimate use of this – for example, if your “scripts”  
are  
coming from an untrusted source – then your argument makes sense.  
Probably  
the easiest approach is to take a language that’s designed for this –  
for  
example, Javascript (so embed Spidermonkey). Probably the best approach  
is to  
figure out how to sandbox Ruby – look at the Try Ruby project for an  
example  
(or at least an attempt).

On the other hand, if you’re talking about a user running your Ruby app  
locally, and potentially extending it themselves, what are you  
protecting them  
from, or yourself from? Unless you’re using JRuby, they already have the  
source, so it’s not an IP issue, right?

Anything else sounds a bit like protecting users from themselves – for  
example, it’s like asking “How do you make a private method/variable  
that no  
one else can see?” Well, instance\_eval is there for a reason.

> I considered loading chunks of Ruby script and using eval() in a safe  
> context,

That’s why I’m thinking it might be an untrusted source.

> and also considered creating a very simple interpreted  
> scripting language in Ruby,

Depends how simple it is. This could certainly be very easy – but on  
the  
other hand, it could grow faster than you mean, and if it’s  
Turing-complete,  
and your app is at all popular, people _will_ be writing applications in  
it.

Do you really want to be responsible for the next PHP, or VBA?

So again… easy way might be roll your own parser, or embed Javascript.  
Hard  
(and right, IMO) way is to use Ruby – eval in a safe context, or run it  
as a  
separate (unprivileged, chrooted) process, etc.

---

<div class="post-metadata">

**Author:** ![puck6633](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/ecb155/32.png) [@puck6633](https://www.ruby-forum.com/u/puck6633)\
**Post date:** [September 7, 2009, 9:20pm UTC](https://www.ruby-forum.com/t/opinion-scripting-in-a-ruby-program/175028/6 "2009-09-07T21:20:48Z")

</div>

On 07.09.2009 18:57, Tristan S. wrote:

> just a few methods, properties, and control structures. So essentially a  
> scripting “language” that can be provided a simple subset of the main  
> program’s functionality in a sandbox context that doesn’t allow file and  
> network I/O, shell access, and all those other nifty things Ruby  
> normally does.
> 
> Something comparable to Unrealscript or Actionscript (which as I  
> understand is essentially Javascript) would work fine, I’m just curious  
> how one would go about implementing such functionality in Ruby. Any  
> further suggestions are welcome, and no one solution may be best, but  
> I’m interested to know what’s out there and what’s possible.

For one, you can do something like this:

class Shell  
class Context  
# custom commands for user code  
def move  
puts “moving…”  
end  
end

# interactive commands

def load(file)  
c = Context.new  
c.instance\_eval(File.read(file))  
nil  
end  
end

Then you can have a file which contains “move” on a line and you’ll see  
the move printed.

There is also $SAFE:  
[http://ruby-doc.org/docs/ProgrammingRuby/html/taint.html#S1](http://ruby-doc.org/docs/ProgrammingRuby/html/taint.html#S1)

Typically you set up an environment and then start another thread which  
restricts $SAFE to provide the sandbox environment.

Also, Try Ruby’s source should contain sandboxing techniques as well  
(see recent posts).

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![puck6633](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/ecb155/32.png) [@puck6633](https://www.ruby-forum.com/u/puck6633)\
**Post date:** [September 7, 2009, 6:57pm UTC](https://www.ruby-forum.com/t/opinion-scripting-in-a-ruby-program/175028/7 "2009-09-07T18:57:14Z")

</div>

Thank you all for your input. I apologize, as it seems I caused some  
confusion with my original post. I’m looking for something that allows  
the user to perform a few simple operations in a sandbox context, rather  
than a framework for programmers to build upon. Something that would  
allow me to compile the main program with ruby2exe and then load – and  
reload without interrupting the execution of the main program – small  
bits of script from an external source (e.g. a file) with.

To bring things into context I have a game in which I would like certain  
objects to be scriptable to some degree. Nothing extremely involved;  
just a few methods, properties, and control structures. So essentially a  
scripting “language” that can be provided a simple subset of the main  
program’s functionality in a sandbox context that doesn’t allow file and  
network I/O, shell access, and all those other nifty things Ruby  
normally does.

Something comparable to Unrealscript or Actionscript (which as I  
understand is essentially Javascript) would work fine, I’m just curious  
how one would go about implementing such functionality in Ruby. Any  
further suggestions are welcome, and no one solution may be best, but  
I’m interested to know what’s out there and what’s possible.

---

<div class="post-metadata">

**Author:** ![puck6633](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/ecb155/32.png) [@puck6633](https://www.ruby-forum.com/u/puck6633)\
**Post date:** [September 8, 2009, 5:08pm UTC](https://www.ruby-forum.com/t/opinion-scripting-in-a-ruby-program/175028/8 "2009-09-08T17:08:20Z")

</div>

You could use TreeTop([http://treetop.rubyforge.org/](http://treetop.rubyforge.org/)) to create a  
mini-language. Just don’t ask me for help. I’m still trying to figure  
out how to use it myself!

---

<div class="post-metadata">

**Author:** ![puck6633](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/ecb155/32.png) [@puck6633](https://www.ruby-forum.com/u/puck6633)\
**Post date:** [September 7, 2009, 11:38pm UTC](https://www.ruby-forum.com/t/opinion-scripting-in-a-ruby-program/175028/9 "2009-09-07T23:38:22Z")

</div>

On Monday 07 September 2009 11:57:18 am Tristan S. wrote:

> I’m looking for something that allows  
> the user to perform a few simple operations in a sandbox context,

The important question for me is, why does this need to be a sandbox?

> Something that would  
> allow me to compile the main program with ruby2exe and then load – and  
> reload without interrupting the execution of the main program – small  
> bits of script from an external source (e.g. a file) with.

If ruby2exe allows for ‘eval’, you could easily do it that way –  
unless,  
again, you want to “save users from themselves” somehow, by ensuring  
that when  
their “script” crashes, it doesn’t bring down your script.

But unless they’re deliberately doing that, I don’t really see what’s  
wrong  
with simply creating a well-defined framework and re-evaling their  
script. As  
an example, look at Rails in development mode.

If you were doing this for Unix, you’d also have the nice strategy of  
forking,  
then evaling (or simply ‘load’ or ‘require’-ing), and communicating with  
the  
parent process via pipes. With a COW-friendly GC (which I think Ruby 1.9  
has),  
this would be lightning-fast and not really more memory than a thread.

But the advantage of the fork-eval strategy isn’t that it’s more of a  
sandbox,  
it’s that they start with a clean slate each time, with all the  
libraries  
loaded.

> To bring things into context I have a game in which I would like certain  
> objects to be scriptable to some degree. Nothing extremely involved;  
> just a few methods, properties, and control structures. So essentially a  
> scripting “language” that can be provided a simple subset of the main  
> program’s functionality

Yes, you’re still talking about something that would be satisfied by  
making it  
a “framework”, by doing things like eval, load, or require, and running  
that  
Ruby code with full privileges.

> in a sandbox context that doesn’t allow file and  
> network I/O, shell access, and all those other nifty things Ruby  
> normally does.

So the question is, what’s wrong with that? Let’s compare:

> Something comparable to Unrealscript

As I understand it, this is essentially meant to script a game, so  
there’s no  
reason you’d restrict it in any way.

> or Actionscript

Which does allow network I/O, it’s just restricted to certain IPs/ports.

> (which as I  
> understand is essentially Javascript)

Not really. I think later versions may have tried to make it a superset  
of  
Javascript, but definitely early on, it was a sad attempt to “improve”  
on  
Javascript.

## Robert K. mentioned some techniques if you really need to sandbox it

$SAFE looks particularly interesting.

I’ve mentioned a few others – probably the most Unix-y way you could do  
this  
is to provide a pipe-based API, where you send text over a pipe to any  
program  
they want, which replies over the same pipe, and is otherwise  
unprivileged and  
chroot’ed. I have no idea how easy this is to do on Windows, though I  
think IE  
now does something similar on Vista.

But the question you haven’t answered yet is why you want it sandboxed  
at all.  
Is the idea that people could be downloading these scripts from the  
Internet?
