Question

In Ruby, I can have a module like:

module Greeter
  def greet
    print "Hello"
  end
end

And my class can get the greet method like this:

class MyClass
  include Greeter
end

obj = MyClass.new
obj.greet

Now, I would like to have my module Greeter implemented in Java instead. I'm using JRuby. I'm unsure about how to create a Ruby module in Java (in such a way that I can do include normally).

For a moment I though of making a Java interface. Including it in my Ruby class doesn't throw errors, but it really isn't the same thing since modules seem to implement the methods, whereas a Java interface doesn't.

Was it helpful?

Solution

Here's how would implement exactly the same code you have above using a Java extension.

Everything here is at the default package level (no package), if you would like to have packages just change the module name.

First, create the Greeter class:

import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;

public class Greeter {

    @JRubyMethod
    public static void greet( ThreadContext context, IRubyObject self ) {
        System.out.printf("Hello from %s%n", self);
    }

}

Then you need the GreeterService to load it:

import org.jruby.Ruby;
import org.jruby.RubyModule;
import org.jruby.runtime.load.BasicLibraryService;

import java.io.IOException;

public class GreeterService implements BasicLibraryService {

    @Override
    public boolean basicLoad(final Ruby runtime) throws IOException {
        RubyModule greeter = runtime.defineModule(Greeter.class.getSimpleName());
        greeter.defineAnnotatedMethods(Greeter.class);

        return true;
    }

}

And with these classes defined, here's how you can use them in a JRuby script:

require 'target/jruby-example.jar'
require 'greeter'

class MyClass
  include Greeter
end

obj = MyClass.new
obj.greet

The jruby-example.jar contains both classes above compiled and packaged. There isn't much else to be done here, now you have your module that you can include anywhere. For a bigger example, just check how the Enumerable module is implemented.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top