Have you ever had had an inkling to interpret JavaScript with in your Ruby code? Well, I have, so I did some investigating and found Spidermonkey – the API that drives Firefox and Thunderbird’s JavaScript Engine. Being a C-library, it would be (relatively) trivial to write a Ruby interface – and thanks to the wonderful wold of the internets, someone has done just that. Unfortunately, the author is Japanese, and the documentation is sparse. Also, the code hasn’t really been updated since 2006 – but it still works, and thankfully someone else has decided to do a little work on it.
Anyway, here my instructions to install spidermonkey and the ruby library on Gentoo. These instructions may or may not work on other Linux distros or OSX (besides the obvious Gentoo specific emerge function).
Install Spidermonkey
Although the libraries links against Spidermonkey 1.7, running the tests ends in a segfault, so 1.6 is the way to go. If you have updated your portage tree, you will need to lock to the specific version:
Install the library
I installed the updated version from matthewd’s git repository, although the extconf.rb file still needs a little tweaking. Also there are a few tests that will still fail – probably nothing that a little C-hacking can’t fix.
Anyway, open extconf.rb and make it look like this:
require 'mkmf'
require 'pkg-config'
def find_smjs(mozjs)
dir_config(mozjs)
#$CFLAGS += " -gdbg"
case CONFIG['target_os']
when /mswin32|mingw|bccwin32/
$defs << " -DXP_WIN"
lib = "js32"
else
$defs << " -DXP_UNIX"
lib = mozjs
end
$defs << " -DNEED_#{mozjs.upcase}_PREFIX"
have_library(lib)
end
if find_smjs('js') or find_smjs('mozjs') or (CONFIG['target_os'] =~ /mswin32|mingw|bccwin32/ and (find_smjs('mozjs') or find_smjs('smjs') or find_smjs('js'))) or
%w(xulrunner-js thunderbird-js mozilla-js).any? do |package|
PKGConfig.have_package(package)
end
create_makefile("spidermonkey")
else
exit 1
end
Finally open spidermonkey.c and find the header include files. Change add these lines before the #else directive
#elif defined NEED_JS_PREFIX
# include <js/jsapi.h>;
# include <js/jshash.h>;
# include <js/jsobj.h>;
Now run the following to build:
ruby extconf.rb
make
sudo make install
If you didn’t have any errors, you should sweet.
Using the library
Now, to parse, compile and execute some javascript code, you need to create a Context, then evaluate the code. So drop this into irb:
require 'spidermonkey'
js = << -JS
function test() {
return 1 + 2;
}
JS
context = SpiderMonkey::Context.new
context.evaluate(js);
context.evaluate('test();')
Irb should output 3, which, last time I checked is still equal to 1+2!
As you can see, you can make multiple calls within the given context, and all of the functions and variables are persistent. I’ll post more notes as I find them.