2

を使用してrubyファイルをjavaクラスにコンパイルすると、justとwith (javaファイルを生成するため)とjustでjrubycコンパイルすると異なる出力が得られます。なんで?jrubycjrubyc --javajavac

例:

最初の方法:

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

2番目の方法:

jrubyc myscript.rb

生成されたクラスはまったく同じであると思いますが、そうではありません。隠れて何をしているのjrubyc

ありがとう!

4

1 に答える 1

3

jrubyc myscript.rbJRuby で使用するために Ruby ファイルをコンパイルし、Java からは使用できないため、AOT という名前が付けられています。コンパイルに使用されるコードは、バイトコードへの変換に使用される通常の JRuby コンパイラです。myscript.class結果を JRuby スクリプトでのみ使用できます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は 2 つの追加オプションが用意されています: --javaand : 最初のオプションは、元のスクリプトで通常行うように、 を--javac使用してコードを JRuby スクリプトにラップする Java ソース コードを生成します。ScriptingContainer2 つ目は、コンパイルされた 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: Bringing Ruby to Javaの Chapter 4, The JRuby Compilerで、これら 2 つの形式について適切に説明しています。

于 2012-09-16T07:54:38.643 に答える