【问题标题】:How to create a Ruby module in Java using JRuby?如何使用 JRuby 在 Java 中创建 Ruby 模块?
【发布时间】:2013-11-20 00:18:58
【问题描述】:

在 Ruby 中,我可以有这样的模块:

module Greeter
  def greet
    print "Hello"
  end
end

我的班级可以像这样获得greet 方法:

class MyClass
  include Greeter
end

obj = MyClass.new
obj.greet

现在,我想用 Java 实现我的模块 Greeter。我正在使用 JRuby。我不确定如何在 Java 中创建一个 Ruby 模块(这样我就可以正常使用include)。

有一段时间我想制作一个 Java 接口。将它包含在我的 Ruby 类中不会引发错误,但它确实不是一回事,因为模块似乎实现了方法,而 Java 接口却没有。

【问题讨论】:

  • 嗯...为什么?这有什么帮助?我认为它会混淆你的代码正在做什么,而且不是很好。
  • 在 jruby 中,出于性能原因,我通常会发现自己将 ruby​​ 代码下推到 java 实现中。
  • @theTinMan:主要是好奇心。坦率地说,隐藏这样的模块对我来说并不是那么糟糕。我正在编写一个游戏开发框架,老实说,最终用户肯定不想乱用这个模块——他们只需要(并且应该)将它包含在他们的 Ruby 类中。

标签: java ruby module jruby


【解决方案1】:

以下是使用 Java 扩展实现与上面完全相同的代码的方法。

这里的所有内容都是默认的包级别(无包),如果您想要包,只需更改模块名称即可。

首先,创建 Greeter 类:

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);
    }

}

那么你需要 GreeterService 来加载它:

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;
    }

}

定义了这些类后,您可以在 JRuby 脚本中使用它们:

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

class MyClass
  include Greeter
end

obj = MyClass.new
obj.greet

jruby-example.jar 包含上面编译和打包的两个类。这里没有太多其他事情要做,现在您有了可以在任何地方包含的模块。举个更大的例子,看看Enumerable 模块是如何实现的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多