torsdag, oktober 05, 2006

JRuby progress

I thought that I should post a little notice about what's happening with JRuby right now. Most of this is available for you if you subscribe to FishEye for JRuby (http://fisheye.codehaus.org/changelog/~rss/jruby/rss.xml).

There are a few very nice innovations going on. The most important is probably that Java-integration has been improved quite substantially. Basically, if the package you need are in the java, javax, org or com packages, you can just refer to classes the same way you refer to them in Java (except for classes that doesn't have a capital initial letter, but you don't do that, do you?). Typical JRuby code could look like this:
 require 'java'

TreeMap = java.util.TreeMap
x = TreeMap.new(java.util.Comparator.impl { |m,o1,o2|
o1 <=> o2
})
Now, there are two new features in here, and one JRuby idiom that should be used in JRuby code. The first feature is to refer to classes by name, simply. The idiom is to import classes into the current namespace by assigning them to constants. The second interesting feature is the 'impl' method, that is available on all interfaces. This method will create an anonymous implementation of the interface, which will call the block when any of the methods in the interface is called. The method name goes in the parameter 'm' in the example. This allows a very clean syntax for implementing one-method-interfaces, like in the example above. Before these we're added, you had to use import_class for each class, then create a class for the interface, and then use this class. The code would easily have doubled for this example.

A few days ago Charles and Tom made me committer in the JRuby project, which obviously feels very good, though slightly nervous. But I've been able to fix a number of very small bugs since then. The more interesting of these, in no order:
  • Correct implementation of default-inspect. (This isn't that interesting for implementations, but it makes debugging much easier)
  • Hash#each didn't yield properly in some edge-cases. This fix was submitted by Miguel, and applied by me.
  • I also added a fix to improve the Java method matching when the methods had a primitive in their arguments. This means that from now on, if you have two Java-methods, foo(float a) and foo(int a), and call it from Ruby with "foo(32)", the float-one won't get called anymore. Pretty nice.
  • A String#crypt implementation, which is based on some stuff I did years ago, which means there are no copyright issues.
  • The flash-issue with Rails (a message placed in the flash doesn't get removed). This was a Marshalling issue, which was quite easy to fix. Big win.
  • Stack overflow when calling non-implemented methods when subclassing an interface. It calls method_missing instead, now.
There are a few things being discussed on the list right now. We will soon commit a readline.rb that checks if the JNI-based GNU readline-bridge is present, and if so uses it. This means that if you want, you can have basic readline in JIRB.

We are talking about the best way to implement OpenSSL support too. This is quite a big thing, though, and as Tom put it "It will be pretty difficult but the person who does it will be worshipped". I'm not sure about the right way to go with implementation either. It seems the available OpenSSL JNI-implementations aren't good enough, so the best route seems to be JSSE. If you have any opinions or suggestions, please get in touch.

In other news, it seems I'm going to be talking about JRuby at JavaForum in Malmö. The date is not final but it seems likely to be the 23 October. If you're in Malmö, please stop by. I'll post more information as soon as everything is clear.

6 kommentarer:

Anonym sa...

Hi Ola,

Ola : Very unique name you have!

very nice blog.

JRuby platform integration : Suppose I want to copy a file to windows clipboard, how easy is it to do today ? What is the recommended approach to do the same ?

Today, I use ActivePerl (on windows) to do my smalltime clipboard needs on the command line. I would like to use Java, preferably JRuby for such tasks. will it be easy for me to do such tasks, going forward ?

Thank you,

BR,
~a(anjan.dev ------ AT ---- gmail)

Anonym sa...

Ola,
Is there a reason we need to have the

Constant = java.package.Constant

syntax? Why not something like

import java.package.Constant

where import is a method defined to do the same constant binding. Is that possible? Seems a little less redundant

Charles Oliver Nutter sa...

yan: I'm not speaking for Ola, because he suggested an import syntax like you describe, but the benefit of the current syntax is that you can assign any name you want to an incoming class:

ListenerForButtons = java.awt.event.ActionListener

my_listener = ListenerForButtons.impl { puts "button pressed!" }

An import implementation would be very easy to create, however...it would just take the class specified and assign it as a like-named constant in the caller's scope. I won't go into that here, but it's certainly possible (without making changes to JRuby internals, I might add).

Ola Bini sa...

Anjan!

Hi. My name is Swedish/Italian. Your's isn't that common either, I believe?

Anyway, regarding platform integration, I would recommend that you use Swing's clipboard-support. I haven't tried it myself, but since Java support in JRuby is very easy to do, you could probably figure it out from Java examples of copy'n'paste. There are no specific JRuby features for this.

Ola Bini sa...

Yan!

As Charles notes, it would be very simple to implement your own version of import.

I will post a simple example that does just this in a minute.

Anonym sa...

Cool, I have not messed too much with bindings but I guess I would have to gain access to the caller's bindings to do this?