理想的にはMRIとJRubyはすべての状況で100%同じように動作しますが、いくつかの小さな違いがあります。 いくつかの違いはバグによるものであり、ここでは報告されていません。 このページは、バグではない違いのためのものです。
スタックトレースの違い
JRubyはJVMベースの言語であるため、Rubyスタックトレース(”バックトレース”)のレンダリング方法にいくつかの違いがあるかもしれません。 そのような場合の部分的なリストは以下の通りです:
- オブジェクトの構築からの”新しい”フレームは、最適化のために存在しない可能性があります。
- Javaで実装されたコアクラスメソッドが表示されます。CRubyが呼び出しを表示するだけのjavaファイルと行番号。二度rbライン。 これは
caller
とcaller_locations
の出力には影響しません。 - JVMスタックからスタックトレースを再構築する方法により、フレームが増えたり減ったりする可能性があります。
- ネストされたブロックは、ネストのレベルを表示しません。
- トップレベルのフレームには、CRubyが””を示す別の名前が表示される場合があります。
一般的に、コードはCRubyと正確に一致する例外バックトレースに依存すべきではありませんが、疑わしい違いがある場合はバグを開いてください。 私たちはできるだけCRubyと一致させるようにしています。
ネイティブC拡張
JRubyはネイティブC拡張を実行できません。 一般的なライブラリはすべて、一般的にJavaネイティブ拡張に移植されています。 また、FFIはCライブラリへのバインディングの一般的な代替手段となったので、それを使用すると、ネイティブ拡張の大きな塊を書く必要がなくなりま
継続とファイバー
JRubyは継続をサポートしていません(Kernel.コールマン)。
ファイバー(区切り付き継続の形式)はJRubyでサポートされていますが、各ファイバーはネイティブスレッドによってサポートされています。 これは、システムが特定のプロセスでスレッドを許可するよりも多くのファイバーを使用しようとすると、リソースの問題につながる可能性があります。
外部プロセスの起動
Microsoft Windowsでは、外部プロセスを起動するときにJRubyは少し賢くなります。 実行可能ファイルがバイナリ実行可能ファイル(.exe
)でない場合、MRIではファイル接尾辞も指定する必要がありますが、JRubyはそれなしで管理します。たとえば、パスにファイルfoo.bat
があり、それを実行したいとします。
system( 'foo' ) # works on JRuby, fails on MRIsystem( 'foo.bat' ) # works both in JRuby and MRI
Forkは実装されていません
JRubyはfork()
がMRIで利用可能なプラットフォームを含め、どのプラットフォームにもfork()
を実装していません。 これは、ほとんどのJvmを安全にフォークできないためです。
ネイティブ-エンディアンはビッグ-エンディアン
JVMはJRubyに互換性のあるCPUを提供するため、JRubyのネイティブ-エンディアンはビッグ-エンディアンです。 これは、次のような形式のString#unpack
やArray#pack
のように、その動作に依存する操作で重要ですI
, i
, S
, とs
。
時間精度
JVMの下でusec
精度を取得することはできないため、Time.now.usec
はナノ秒精度の値を返すことはできません。 これはもはやPOSIXプラットフォームの下では当てはまりません(JRuby9.1以降)。
irb(main):004:0> Time.now.usec=> 815414
Windowsではネイティブシステムコールが実装されていないため、JVMミリ秒精度のフォールバックがあります。コードでusec
の精度を考慮するときは、これに注意してください。
> Time.now.usec=> 582000
スレッドの優先度
注:少なくともJRuby1.7.6からは、Rubyスレッドの優先度はJavaスレッドの優先度にマップされているため、このセクションは正確ではありません。MRIとJRubyで同じ優先度を使用することができます。
MRIでは、スレッドの優先度はFixnum(ネイティブスレッドが有効な場合)または-3の任意の値に設定できます。.3(そうでない場合)。 デフォルト値は0です。
Jrubyでは、スレッドはJavaスレッドによってサポートされており、優先度の範囲は1から10で、デフォルトは5です。 この範囲外の値をThread#priority=
に渡すと、優先度は1または10に設定されます。注:JVMが優先順位を無視する可能性があること、それは本当にターゲットOSに依存し、(古い)Javaでは、それらを使用するために余分な-XX:UseThreadPriorities
を渡す必要があります。
SystemStackError
JRubyはSystemStackError
から救出できません。 コードがこれに依存している場合は、Java::JavaLang::StackOverflowError
をキャッチしようとする必要があります。 詳細については、このチケットを参照してください。
Argumentless’proc’
引数なしでproc
を指定し、メソッドがブロックを渡された場合、Rubyは渡されたブロックをキャプチャしてしまいます。 一部の人々はこれを発見し、proc.call
の珍しいパターンにつながります。 私たちはこの動作をサポートしていません。 問題は、関数が比較的一般的であるためprocですが、proc { #some code }
ようなprocのすべての使用を最適化解除するように強制します。 推奨される回避策は、アンパサンドdef foo(&my_proc)...
を使用してブロックを明示的に宣言することです。 アナログ動作をprocにしたい場合は、裸のproc呼び出しとまったく同じように動作するProc.new
も許可します。