2008-04-01 @ 15:00

New Ruby Implementation - Brobinius

Brobinius version 1.0.0 has been released!

I am happy to annouce the first release of my new fork of Ruby called Brobinius. The goal of Brobinius is to implement new language features that I have noticed to be completely missing.

For example, Object#tase! The tase method is featured in many other languages but is sadly missing from Ruby. Brobinius has a fully implemented tase! method.

>> x = Class.new => #<Class:0x3632ec> >> x.tase! RuntimeError: Don't tase me bro from (irb):2:in `tase!' from (irb):6 >> ~~~

Brobinius also has fully serializable kittenuations. You can create and serialize your kittenuations, then pick up your snuggling where you left off. For example:

>> lol = Kittenuation.new { ?> look_cute >> throw :yarn >> look_cute >> } => #<Kittenuation:0x366244> >> lol.snuggle >> Marshal.load(Marshal.dump(lol)).snuggle ~~~

Since Brobinius’s kittenuations are serializable, you can share them over the network with friends!

Brobinius also features screencasts with automatic YouTube uploads. All you have to do write your program, then pass the –screencast option to Brobinius. Brobinius will automatically create a screencast of your program and upload it to YouTube:

$ brobinius --screencast my_code.rb ~~~

You can even add the –geoff flag to create screencasts with Geoffrey Grosenbach doing the voice over.

read more »

2008-04-23 @ 11:22

Take it to the limit one more time

Sup bros. I need to post in this thing more often. Yesterday, someone tipped over my scooter again. I’m getting kind of tired of that.

Anyway, its time for me to write about this. RKelly is pretty much dead. For the past few months, John and I have been working on RKelly’s replacement called Johnson. Basically we’re now putting a ruby wrapper around Mozilla’s Spidermonkey. The project is coming along quite nicely. Ruby objects can be passed in to javascript land, and javascript objects can be passed back in to ruby land.

For example, we can define an alert function in our javascript context:

require 'johnson'

ctx = Johnson::Context.new
ctx['alert'] = lambda { |x| puts x }
ctx.evaluate('alert("Hello world!");')

Johnson::Context#evaluate will also return the last statement evaluated. We can evaluate an expression, and manipulate that expression in ruby land. For example, I’ll create an object in javascript, return it to ruby land, then access a property of the javascript object:

require 'johnson'

ctx = Johnson::Context.new
obj = ctx.evaluate('var foo = { x: "hello world" }; foo')
puts obj.x  # => 'hello world'

We can even do the reverse by stuffing ruby objects in to the context:

A = Struct.new(:foo)

ctx = Johnson::Context.new
ctx['alert'] = lambda { |x| puts x }
ctx['a'] = A.new("bar")
ctx.evaluate('alert(a.foo);') # => 'bar'

But it gets better. We added a top level variable called “Ruby” that lets you access constants and globals from Ruby land. We can rewrite the previous example completely in javascript:

ctx = Johnson::Context.new
ctx.evaluate("var x = new (new Ruby.Struct(Johnson.symbolize('foo')));")
ctx.evaluate("x.foo = 'bar'")
puts ctx.evaluate('x').foo # => 'bar'
puts ctx.evaluate('x').class # => #<Class:0x49714>

Since the ‘Ruby’ constant delegates to Object, you can access any constant. Including ones you’ve defined yourself. We could, for example, look up a bunch of User records through rails:

ctx = Johnson::Context.new
ctx['alert'] = lambda { |x| puts x }
ctx.evaluate(<<-END
             for(var user in Ruby.User.find(Johnson.symbolize('all'))) {
               alert(user.first_name());
             }
             END
            )

You might be wondering what this Johnson.symbolize business is about. Since Javascript doesn’t have a concept of a symbol, we’ve created a helper to “mark” a string as a symbol and pass it back in to ruby land.

To conclude this update about my Johnson, I’d like to show off an interactive shell for Johnson (thanks to Brohuda Katz). Johnson has an interactive shell that lets you try things out in javascript land or ruby land, and let you quickly switch between the two. Typing ‘js’ will put in you the javascript shell, ‘rb’ will switch you to the ruby shell. In the ruby shell, you can use the ‘cx’ variable to get ahold of you javascript context: $ ruby -I lib bin/johnson js> var x = { foo: 'bar', hello: function() { return 'world' } }; => nil js> rb rb> cx['x'].foo => "bar" rb> cx['x'].hello() => "world" rb> ~~~ We aren't quite ready for a release yet, but if you'd like to play around with Johnson, you can pull it down from github here. Just run 'rake', and you should have it compiled and running!

My next Johnson related post will be about Javascript parse trees and Javascript code generation.

read more »