加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何将Jruby proc / block / closure返回给java并调用它

发布时间:2020-12-17 01:59:45 所属栏目:百科 来源:网络整理
导读:我希望能够将嵌入式j ruby实例中的块返回到常规 java.我的 java代码应该能够传递所需的参数(假设它知道正确的arity),然后接收结果.任何样品将不胜感激. 解决方法 如果你可以直接嵌入,使用 JavaEmbedUtils并在定义你的proc / block / closure的ruby代码字符串
我希望能够将嵌入式j ruby实例中的块返回到常规 java.我的 java代码应该能够传递所需的参数(假设它知道正确的arity),然后接收结果.任何样品将不胜感激.

解决方法

如果你可以直接嵌入,使用 JavaEmbedUtils并在定义你的proc / block / closure的ruby代码字符串上调用eval,或者让你的ruby代码实现一个接口,其中某些方法返回你的proc / block / closure.以下两个数字相加的令人难以置信的例子:

SampleApp.java

import org.jruby.Ruby;
import org.jruby.RubyRuntimeAdapter;
import org.jruby.RubyFixnum;
import org.jruby.RubyProc;
import org.jruby.javasupport.JavaEmbedUtils;
import org.jruby.runtime.Block;
import org.jruby.runtime.ThreadContext;
import java.util.ArrayList;

class SampleApp {
        public static void main(String[] args) {

                // Create runtime instance
                Ruby runtime = JavaEmbedUtils.initialize(new ArrayList());

                // Parameters
                RubyFixnum paramA = new RubyFixnum(runtime,1);
                RubyFixnum paramB = new RubyFixnum(runtime,2);

                // Runtime eval method
                RubyRuntimeAdapter evaler = JavaEmbedUtils.newRuntimeAdapter();
                RubyProc additionProcFromEval = (RubyProc)evaler.eval(runtime,"Proc.new { |a,b| a + b }");
                printProcResult(runtime,additionProcFromEval,paramA,paramB);

                // Interface implementation method
                SomeInterfaceImpl someImpl = new SomeInterfaceImpl();
                RubyProc additionProcFromInterface = (RubyProc)someImpl.getAdditionProc();
                printProcResult(runtime,additionProcFromInterface,paramB);

                // Shutdown and terminate instance
                JavaEmbedUtils.terminate(runtime);
        }

        protected static void printProcResult(Ruby runtime,RubyProc proc,RubyFixnum paramA,RubyFixnum paramB) {
                Block block = proc.getBlock();
                ThreadContext threadContext = ThreadContext.newContext(runtime);
                int result = (Integer)block.call(threadContext,paramB).toJava(new Integer(0).getClass());
                System.out.println("Result = " + result);
        }
}

SomeInterface.java

interface SomeInterface {
    org.jruby.RubyProc getAdditionProc();
}

SomeInterfaceImpl.rb

require 'java'
class SomeInterfaceImpl

        include Java::SomeInterface

        java_signature 'org.jruby.RubyProc getAdditionProc()'
        def getAdditionProc()
                return Proc.new { |a,b| a + b }
        end

end

这就是你可以测试的方式:

javac -classpath jruby.jar SomeInterface.java
jrubyc --javac -cp . SomeInterfaceImpl.rb
javac -cp jruby.jar:. SampleApp.java
java -cp jruby.jar:. SampleApp

参考文献:

https://github.com/jruby/jruby/wiki/DirectJRubyEmbedding

http://tommy.chheng.com/2010/06/20/call-a-jruby-method-from-java/

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读