Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News JavaScript Meets Ruby: John Barnette Explains Johnson

JavaScript Meets Ruby: John Barnette Explains Johnson

This item in japanese

Some technologies are so unique and unusual we sometimes question why they exist in the first place. Segway's personal transporter is one example, and Ruby's Johnson library to access JavaScript from Ruby is another. To understand this technology we had an online chat with Johnson's creator and lead developer John Barnette in Seattle.

But before we start let's bring some context into this topic. AJAX relies primarily on the availability of a DOM, an XMLHTTPRequest object and capable JavaScript to perform what looks like a desktop app on a website or what we refer to as Web2.0. Few developers however have felt the need to build a bridge between JavaScript on the client and Ruby on the server. Johnson is such a project, it's 100% open source and it does have very interesting practical applications.

Johnson's purpose however is to shed light on what goes behind the scenes and make automated AJAX testing possible. John's take on it:

Johnson got created for a couple of reasons. First, Aaron Patterson -- who created Mechanize -- has been getting more and more requests from people who would like to interact with highly dynamic websites‚ we'd like Mechanize to behave as much like a server-side browser as possible, including dynamic page behaviors and DOM manipulation, and Johnson is a stepping-stone on the way to that functionality. Secondly it was the geeky desire to see how smoothly we could get objects and metaphors moving between the two languages.

However Johnson is not just another screen scraping utility like Mechanize, it is more a browser like component without a real browser behind it. It allows for testing across a multitude of browsers, and automation of those tests. John commented on this:

For me, it's more about being able to have the same fast test cycle with JavaScript that I do with existing Ruby tools, like autotest. Writing JavaScript frameworks is a pain when testing requires runs across multiple browsers to verify behavior even for the smallest changes. With Johnson, I can run my tests without the overhead of a real browser.

Of course having a tool like Johnson is not enough, eventually real browser testing will be needed, but a big part of automated repetitive testing can be taken care of with little effort.

Another unique capability of Johnson that Aaron Peterson highlighted is the ability to actually mix Ruby and JavaScript code on the same source (Embedded JavaScript or EJS.) This is a very unusual functionality, so we asked John why they did this; here is his take on it:

We came up with EJS more as a proof-of-concept than anything serious, although it was a very good test of the language generation. I don't use Johnson to write views in JavaScript, though there's probably enough functionality working now that you could do something like Jaxer.

So it is clear that was not the purpose of the tool, but someone could fork it in that direction, and actually this has happened already [GitHub link to fork] here.

Jaxer for those unfamiliar with it, it's a developer environment where JavaScript can actually run on the client and on the server. John had great respect for the project though:

Jaxer is very ambitious. I haven't dug into the code very deeply, but it looks like they're embedding all of Mozilla: DOM, SpiderMonkey, everything, on the server side. I think that's very cool, but I don't necessarily think that it's going to help folks with lots of client-side experience write good server-side applications: The barrier for folks is generally around concepts, not language. The fact that you're using JavaScript on both sides is great, but it doesn't automatically make server-side programming easy.

The problem, in John's view, is more a question of how far can JavaScript can go as a language, and not so much whether it can do the job or not. Recent developments in JavaScript like Google's Just In Time compiler for Chrome proof there is a lot of potential in JavaScript notwithstanding its limitations. But server programming is fairly new still for JavaScript. In John's opinion one of JavaScript weaknesses is that there is no strong general-purpose standard library; there is an array of competing frameworks, not all of them at the level of a standard yet.

On the Chrome theme John had some good news to share:

It's worth mentioning that while Johnson currently depends on SpiderMonkey, the public API is runtime-agnostic: One of our folks is working on a bridge for V8 (Matthew Draper; our esteemed member from Australia) and I'm hoping to see if the JavaScriptCore/Squirrelfish public API provides enough functionality for us to embed as well. I'd really like to be able to test code on multiple runtimes with a flip of the switch.

In the meantime having a separation of Server languages: Ruby on Rails on one side and JavaScript on the other seems to be the best choice we have. A hybrid optimized for language and task at hand. In this regard Johnson is very valuable since it allows

to prototype better server-side/standard libraries for JavaScript outside the Browser. It's a lot easier to prototype a JS.File API if you can transparently bridge to Ruby, as compared to writing native implementations in C or C++ or even Java.

Another concern is how to use Johnson in an everyday development shop. For John it is ideal for continuous integration testing and autotest sessions of AJAX functionality.

While there is no tool ready yet that behaves like a programmable or scriptable Mechanize, it could eventually be developed. In the meantime the team is concentrating on providing a viable server-side DOM implementation. They are pursuing several alternatives; the good news is that it seems a solution will be found. John comments on the subject:

We're pursuing a couple of avenues there. We're working with John Resig on env.js, which is looking to provide a JS implementation of the DOM, with minimal runtime-specific portions for XML/HTML parsing, threading, and network requests. We're also looking at a solution that uses libxml's HTML parser, I think we'll probably end up with a libxml based solution.

On the subject of automation and the ability to see values AJAX delivers; FirePHP is a tool that integrates with Firebug's console. Asked whether something like that could be implemented using Johnson for the Ruby world, John said:

Ah, very cool. Johnson's probably to the point where you could get that going as a Rails plugin pretty easily‚ One of us should write that!

Another strength of Johnson as a project is the quality of the team behind it, besides Mr. Barnette they have Yehuda Katz, Aaron Peterson and Matthew Draper.

Yehuda, Matthew, and Aaron and I were all working independently on viable Ruby bindings for JavaScript. When we found out, we hashed things out and merged. Yehuda's spent a lot of effort getting the jQuery test suite up and running inside Johnson‚ he wants fast browser less testing and prototyping. Aaron's most interested in page automation, and Matthew is actually running a fair amount of production applications with JS runtimes on the server, so he's interested in making sure it's robust.

Finally, when asked about the future and what a 1.0 of Johnson will bring us, John says:

The big non-negotiable for 1.0 is being able to provide a viable browser-less DOM!

Rate this Article