2

当我使用 将 ruby​​ 文件编译为 java 类时,使用 just和 with (生成 java 文件)和 justjrubyc编译时会得到不同的输出。为什么?jrubycjrubyc --javajavac

例子:

第一种方法:

jrubyc --java myscript.rb
javac -cp .:./jruby-complete.jar myscript.java

第二种方法:

jrubyc myscript.rb

我希望生成的类完全相同,但事实并非如此。幕后在做什么jrubyc

谢谢!

4

1 回答 1

3

jrubyc myscript.rb编译 Ruby 文件以供 JRuby 使用,并且不能从 Java 中使用,因此名称为 AOT。用于编译它的代码是用于转换为字节码的普通 JRuby 编译器。您只能使用myscript.classJRuby 脚本中的结果,例如使用require 'myscript'. 使用时javap

ubuntu@ubuntu:/tmp$ javap myscript
Compiled from "myscript.rb"
public class myscript extends org.jruby.ast.executable.AbstractScript {
  public myscript();
  public static org.jruby.runtime.builtin.IRubyObject __file__(myscript, org.jruby.runtime.ThreadContext, org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.builtin.IRubyObject[], org.jruby.runtime.Block);
  public org.jruby.runtime.builtin.IRubyObject __file__(org.jruby.runtime.ThreadContext, org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.builtin.IRubyObject[], org.jruby.runtime.Block);
  public static org.jruby.runtime.builtin.IRubyObject class_0$RUBY$MyScript(myscript, org.jruby.runtime.ThreadContext, org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.Block);
  public static org.jruby.runtime.builtin.IRubyObject method__1$RUBY$run(myscript, org.jruby.runtime.ThreadContext, org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.Block);
  public static org.jruby.runtime.builtin.IRubyObject method__1$RUBY$run(myscript, org.jruby.runtime.ThreadContext, org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.builtin.IRubyObject[], org.jruby.runtime.Block);
  public static org.jruby.runtime.builtin.IRubyObject class_0$RUBY$MyScript(myscript, org.jruby.runtime.ThreadContext, org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.builtin.IRubyObject[], org.jruby.runtime.Block);
  public org.jruby.runtime.builtin.IRubyObject load(org.jruby.runtime.ThreadContext, org.jruby.runtime.builtin.IRubyObject, boolean);
  public static void main(java.lang.String[]);
}

我们看到扩展类继承org.jruby.ast.executable.AbstractScript并定义了很多内部方法,所以很明显这段代码是供 JRuby 的 AST 使用的。

这就是jrubyc提供两个额外选项的原因:--java--javac:第一个生成 Java 源代码,使用 将代码包装到 JRuby 脚本中ScriptingContainer,就像您通常使用原始脚本一样;第二种直接产生编译后的Java类。此代码使用特定的 Java 生成器代码,该代码使用指令,例如为java_signatureJava 方法提供 Java 所期望的正确签名。再次使用javap时:

ubuntu@ubuntu:/tmp$ jrubyc --javac myscript.rb
ubuntu@ubuntu:/tmp$ javap MyScript
Compiled from "MyScript.java"
public class MyScript extends org.jruby.RubyObject {
  public static org.jruby.runtime.builtin.IRubyObject __allocate__(org.jruby.Ruby, org.jruby.RubyClass);
  public MyScript();
  public java.lang.Object run();
  static {};
}

该类以大写 M 开头,并继承RubyObject. 类中定义的方法将公开以供 Java 使用。

使用 JRuby:将 Ruby 引入 Java在第 4 章, JRuby 编译器中对这两种形式进行了很好的描述。

于 2012-09-16T07:54:38.643 回答