views:

258

answers:

3

I'd like my rack application to be able to interface with a server-side javascript engine.

As of now the only way i know this could be possible, is by running JRuby and Rhino on the JVM, but I'm hoping for a leaner solution.

Has anyone heard of another, more rubyish perhaps, option ?

Edit : Reading the comments I'm starting to think I've been mistaken assumig that having both JRuby and Rhino run on the JVM would imply some interoperability between ruby and javascript...?
That's not a desirable solution for me anyhow, but still i'd like to clear that up.

+3  A: 
  • Johnson is a RubyGem that turns the Mozilla SpiderMonkey JavaScript engine into an MRI C extension and allows very deep integration between Ruby and JavaScript,
  • there is a fork of Johnson which replaces the SpiderMonkey engine with the Mozilla TraceMonkey engine and
  • Lyndon is like Johnson but with JavaScriptCore instead of SpiderMonkey and MacRuby instead of MRI.

I think I also remember someone working on embedding V8 with MRI, but I can't find the reference right now.

The main problem with Johnson is that MRI is an incredibly crappy language implementation that leaks memory left and right, and the only language implementation in the world that could possibly be even more crappy is SpiderMonkey. Thus, the TODO list in the Johnson Git repository doesn't exactly inspire confidence; it only contains one item, and I quote literally:

Stop freaking segfaulting.

Lyndon is built on a much better foundation, but it obviously requires running OSX on the server. Plus, MacRuby hasn't been released yet.

I think JRuby+Rhino is probably the most stable option, although you will have to build the integration yourself: they are just two independent language implementations that happen to live on the same VM, but there is no integration between them.

A different take on the problem is RKelly which is a JavaScript parser and execution engine written in Ruby.

As an alternative you could try to approach the problem from a different direction: instead of keeping your application logic in JavaScript and running that both on the client and the server, you could keep your application logic in Ruby and run that on the server and the client: there are a couple of compilers out there that can compile (a subset of) Ruby to JavaScript. On of them is RubyJS. (There is also HotRuby, which is a YARV bytecode interpreter written in JavaScript, but that would very likely be tremendous overkill for what you are doing.)

And last but not least you could do what Rails originally did with their JavaScript helpers: you neither define your logic in Ruby nor JavaScript, instead you define it once in an internal Ruby DSL and generate both the Ruby and JavaScript logic from that.

Jörg W Mittag
Thanks for all the suggestions Jörg, nice write up.
julien
+1  A: 

Have a look at The Ruby Rhino. It uses jruby and rhino to embed javascript into your ruby environment. Among other things, it supports safe evaluation, calling ruby functions from javascript and vice-versa(javascript functions from ruby)

There is also "The Ruby Racer" which embeds v8 into MRI. This is still very much pre-alpha phase, but I hope to have a useable version sometime in march of next year

Another engine I know of is Snarl which also uses jruby and rhino to a similar effect.

Charles Lowell
well something like ruby racer would ultimately be the best solution, but it's nice to see that ruby rhino exists in the meantime
julien
@Charles - Record some more drunk and retired please!
Skilldrick
@Skilldrick We've been getting back into gear lately. Now that cote is next door it's alot easier. Stay tuned for this Friday!
Charles Lowell
@Charles Rock and roll :)
Skilldrick
A: 

The Ruby Racer is now out of pre-alpha and is hovering somewhere between alpha and beta. It now supports:

  • calling ruby code from javascript
  • calling javascript functions from ruby
  • embedding ruby objects into the javascript scope.
  • letting ruby objects be your javascript scope
Charles Lowell
Very impressive Charles ! Keep it up this looks terrific, had to change the accepted answer !
julien