当我使用jrubyc
将ruby文件编译到java类时,在使用jrubyc
和jrubyc --java
进行编译(生成java文件)时,我获得了不同的输出{1}}。为什么呢?
示例:
第一种方法:
javac
第二种方法:
$ jrubyc --java myscript.rb
$ javac -cp .:./jruby-complete.jar myscript.java
我希望生成的类完全相同,但它们不是。什么是$ jrubyc myscript.rb
在幕后做什么?
谢谢!
答案 0 :(得分:2)
jrubyc myscript.rb
编译用于JRuby消费的Ruby文件,不能从Java使用,因此名称为AOT。用于编译它的代码是用于转换为字节码的普通JRuby编译器。您只能在JRuby脚本中使用生成的myscript.class
,例如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源代码,使用ScriptingContainer
将代码包装到JRuby脚本,就像你通常用原始剧本一样;第二个直接生成编译的Java类。此代码使用特定的Java生成器代码,该代码使用诸如java_signature
之类的指令为Java方法提供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使用。
Using JRuby在第4章 JRuby编译器中对这两种形式有很好的描述。