bár ideális esetben az MRI és a JRuby minden helyzetben 100% – ban ugyanúgy viselkedne, vannak kisebb különbségek. Néhány különbség a hibáknak köszönhető,és ezek itt nem szerepelnek. Ez az oldal olyan különbségekre vonatkozik, amelyek nem hibák.
Veremkövetési különbségek
mivel a JRuby egy JVM-alapú nyelv, láthat némi különbséget a Ruby verem nyomainak (“visszalépések”) megjelenítésében. Az ilyen esetek részleges listája az alábbiakban található:
- az objektum felépítéséből származó “új” keret az optimalizálások miatt nem jelenhet meg.
- a Java-ban megvalósított Core class módszerek a-t mutatnak .java fájl és sorszám, ahol CRuby csak megmutatja a hívást .rb vonal kétszer. Ez nem érinti a
caller
éscaller_locations
kimenetet. - több vagy kevesebb képkocka lehet annak köszönhetően, hogy hogyan rekonstruáljuk a verem nyomát a JVM veremből.
- a beágyazott blokkok nem mutatják a fészkelés szintjét.
- a legfelső szintű keretek eltérő neveket mutathatnak, ahol CRuby “”-t mutat.
általánosságban elmondható, hogy a kód nem támaszkodhat a CRuby-nak megfelelő kivételekre, de ha megkérdőjelezhető különbség van, kérjük, nyisson meg egy hibát. Igyekszünk a lehető legszorosabban egyeztetni Crubyt.
natív C kiterjesztések
a JRuby nem tudja futtatni a natív C kiterjesztéseket. A népszerű könyvtárakat általában Java natív Kiterjesztésekbe portolták. Továbbá, most, hogy az FFI a C könyvtárakhoz való kötődés népszerű alternatívájává vált, annak használata kiküszöböli annak szükségességét, hogy nagy mennyiségű natív kiterjesztést írjon.
folytatások és szálak
a JRuby nem támogatja a folytatásokat (Kernel.callcc).
a szálakat (a körülhatárolt folytatás egyik formáját) a JRuby támogatja, de mindegyik szálat natív szál támasztja alá. Ez erőforrás-problémákhoz vezethet, amikor több szálat próbál használni, mint amennyit a rendszer lehetővé tesz egy adott folyamatban.
külső folyamatok meghívása
Microsoft Windows rendszeren a JRuby egy kicsit okosabb a külső folyamatok indításakor. Ha a futtatható fájl nem bináris futtatható fájl (.exe
), akkor az MRI megköveteli, hogy a fájl utótagját is megadja, de a JRuby nélküle kezeli.
tegyük fel például, hogy foo.bat
fájl van az elérési úton, és szeretné futtatni.
system( 'foo' ) # works on JRuby, fails on MRIsystem( 'foo.bat' ) # works both in JRuby and MRI
a Fork nincs megvalósítva
a JRuby nem valósítja meg a fork()
– ot egyetlen platformon sem, beleértve azokat is, ahol a fork()
elérhető az MRI-ben. Ennek oka az a tény, hogy a legtöbb JVM-et nem lehet biztonságosan villázni.
a natív Endian a Big Endian
mivel a JVM kompatibilis CPU-t mutat be a JRuby számára, a JRuby natív endianitása a Big Endian. Ez nem számít a műveletek, amelyek függnek, hogy a viselkedés, mint a String#unpack
és Array#pack
formátumok, mint I
, i
, S
, és s
.
Időpontosság
mivel JVM alatt nem lehet usec
pontosságot elérni, a Time.now.usec
nem adhat vissza értékeket nanoszekundumos pontossággal. A POSIX platformon már nem ez a helyzet (a JRuby 9.1 óta).
irb(main):004:0> Time.now.usec=> 815414
Windows rendszeren a natív rendszerhívás nem valósul meg, így a JVM milliszekundumos pontosságú tartalék.Tartsa ezt szem előtt, amikor a kód usec
pontosságára számít.
> Time.now.usec=> 582000
Szálprioritás
megjegyzés: legalább a JRuby 1.7.6-tól kezdve a Ruby szálprioritások Java szálprioritásokhoz vannak hozzárendelve, így ez a szakasz nem pontos-ugyanazt a prioritást használhatja az MRI és a JRuby esetében is.
az MRI-ben a Szálprioritás bármilyen értékre állítható a Fixnumban (ha a natív szálak engedélyezve vannak) vagy -3..3 (ha nem). Az alapértelmezett érték 0.
a JRuby-ban a szálakat Java szálak támogatják, és a prioritás 1-től 10-ig terjed, alapértelmezés szerint 5. Ha ezen a tartományon kívül eső értéket ad át Thread#priority=
értékre, a prioritás 1 vagy 10 lesz.
megjegyzés: az, hogy a JVM figyelmen kívül hagyja a prioritásokat, valójában a cél operációs rendszertől függ, és (régebbi) Java esetén át kell adnia az extra -XX:UseThreadPriorities
– et, hogy használni lehessen őket.
SystemStackError
a JRuby nem képes megmenteni a SystemStackError
– től. Ha a kód erre támaszkodik, akkor inkább meg kell próbálnia elkapni a Java::JavaLang::StackOverflowError
. További információkért lásd ezt a jegyet.
Argumentless ‘proc’
ha a proc
– et argumentumok nélkül adja meg, és a metódus történetesen egy blokkot kapott, akkor a Ruby végül rögzíti az átadott blokkot. Néhány ember felfedezi ezt, és ez egy ritka, proc.call
mintához vezet. Nem támogatjuk ezt a viselkedést. A probléma az proc mivel a funkció viszonylag gyakori, de arra kényszerít minket, hogy deoptimalizáljuk a proc összes felhasználását, például proc { #some code }
. Az ajánlott munka körül, hogy állapítsa meg a blokk kifejezetten egy ampersand def foo(&my_proc)...
. Ha azt szeretnénk, analóg viselkedés proc is lehetővé Proc.new
amely pontosan ugyanúgy működik, mint egy csupasz proc hívást.