The Artima Developer Community
Sponsored Link

Java Buzz Forum
Hiding your Ruby behind Java interfaces

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
dion

Posts: 5028
Nickname: dion
Registered: Feb, 2003

Dion Almaer is the Editor-in-Chief for TheServerSide.com, and is an enterprise Java evangelist
Hiding your Ruby behind Java interfaces Posted: May 15, 2007 12:07 AM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by dion.
Original Post: Hiding your Ruby behind Java interfaces
Feed Title: techno.blog(Dion)
Feed URL: http://feeds.feedburner.com/dion
Feed Description: blogging about life the universe and everything tech
Latest Java Buzz Posts
Latest Java Buzz Posts by dion
Latest Posts From techno.blog(Dion)

Advertisement

I often get side tracked seeing JRuby as just a cure for Rails deployment issues. Although it is huge to think of a fast Ruby container, and having access to JVM internals for management and such, JRuby also has a fantastic set of Java integration features.

This means that while you are in Java-land, you can actually hide Ruby implementations of features behind nice Java interfaces. Rob Harrop showed off some of this at his JRuby DSL talk at JavaOne last Friday.

Here is a simple example of having Java code doing some kind of calculation, and behind the scenes the implementation is in Ruby.

The pieces are:

  • Java client code that does the calculation
  • Factory to return the object that can do the calculation
  • Calculation interface
  • The Ruby object that does the work
  • The Ruby file that makes the object implement the interface

Java Client Code

Calculator c = CalculatorFactory.getCalculator();
String calculation = "1 + 3";
System.out.println("Calculate(" + calculation + ") = " +  c.calculate(calculation));

Calculation interface

public interface Calculator {
    public String calculate(String calculation);
}

Calculator Factory

The factory loads up the Ruby code, and then munges the Ruby object to return it back to Java-land as the Calculator interface:

    public static Calculator getCalculator() {
        Ruby runtime = Ruby.getDefaultInstance();

        try {
            runtime.evalScript(getContents("rcalculator.rb"));
            runtime.evalScript(getContents("makejcalculator.rb"));
        } catch (Exception e) {
            System.err.println(e.toString());
            e.printStackTrace();
        }

        Object c = runtime.evalScript("RCalculator.new");
        c = JavaEmbedUtils.rubyToJava(runtime, (IRubyObject) c, Calculator.class);
        return (Calculator) c;
    }
The magic is done in JavaEmbedUtils.rubyToJava(runtime, (IRubyObject) c, Calculator.class);.

Ruby implementation of Calculator

The Ruby implementation is simple:

class RCalculator
 def calculate(s)
  return eval(s).to_s
 end
end
To make it implement Calculator we monkey patch it by also loading the makejcalculator.rb file:
require 'java'

class RCalculator
  include Java::Calculator
end

You could obviously do this all at once, but this pattern can allow you to share the Ruby code, and you may have other Ruby that you can't just hack on.

This pattern will be common, so having a java_implement RCalculator, Java::Calculator simple piece of meta-code is useful.

All in all, JRuby gives you everything you need to do as much of your business logic in Ruby, and never expose it. This gives me thoughts of working on a Java team and telling my team mates about the interfaces they can use, and writing the entire app in Ruby behind the scenes ;)

Read: Hiding your Ruby behind Java interfaces

Topic: JavaFX: Revenge of the re-branding Previous Topic   Next Topic Topic: ReSharper 2.5.2 Released, Uses No-License Evaluation Model

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use