även om MR och JRuby helst skulle bete sig 100% lika i alla situationer, finns det några mindre skillnader. Vissa skillnader beror på buggar, och de rapporteras inte här. Denna sida är för skillnader som inte är buggar.
Stack Trace Differences
eftersom JRuby är ett JVM-baserat språk kan du se vissa skillnader i hur Ruby stack traces (”backtraces”) återges. En partiell lista över sådana fall är nedan:
- den” nya ” ramen från att konstruera ett objekt kanske inte finns på grund av optimeringar.
- Kärnklassmetoder som implementeras i Java kommer att visa en .java-fil och radnummer där CRuby bara skulle visa samtalet .rb linje två gånger. Detta bör inte påverka utmatningen
caller
ochcaller_locations
. - det kan finnas fler eller färre ramar på grund av hur vi rekonstruerar ett stackspår från JVM-stacken.
- kapslade block visar inte nestningsnivån.
- toppnivåramar kan visa olika namn där CRuby visar””.
i allmänhet bör koden inte förlita sig på undantag backtraces matchar CRuby exakt, men när det finns en tvivelaktig skillnad vänligen öppna en bugg. Vi försöker matcha CRuby så nära som möjligt.
Native C-tillägg
JRuby kan inte köra native C-tillägg. Populära bibliotek har alla i allmänhet portats till Java Native Extensions. Också, nu när FFI har blivit ett populärt alternativ till bindning till C-bibliotek, med hjälp av det undanröjer behovet av att skriva en stor del av infödda tillägg.
fortsättningar och fibrer
JRuby stöder inte fortsättningar (kärna.callcc).
fibrer (en form av avgränsad fortsättning) stöds på JRuby, men varje fiber stöds av en inbyggd tråd. Detta kan leda till resursproblem när man försöker använda fler fibrer än Systemet tillåter trådar i en given process.
anropa externa processer
på Microsoft Windows är JRuby lite smartare när du startar externa processer. Om den körbara filen inte är en binär körbar (.exe
), kräver Mr att du också ger filsuffixet, men JRuby klarar sig utan det.
säg till exempel att du har fil foo.bat
på din väg och vill köra den.
system( 'foo' ) # works on JRuby, fails on MRIsystem( 'foo.bat' ) # works both in JRuby and MRI
gaffel är inte implementerad
JRuby implementerar inte fork()
på någon plattform, inklusive de där fork()
finns i Mr. Detta beror på det faktum att de flesta JVM inte kan gafflas säkert.
Native Endian är Big endian
eftersom JVM presenterar en kompatibel CPU till JRuby, är jrubys nativa endianness Big Endian. Detta spelar roll för operationer som beror på det beteendet, som String#unpack
och Array#pack
för format som I
, i
, S
, och s
.
tidsprecision
eftersom det inte är möjligt att erhålla usec
precision under en JVM, kan Time.now.usec
inte returnera värden med nanosekundsprecision. Detta är inte längre fallet under en POSIX-plattform (sedan JRuby 9.1).
irb(main):004:0> Time.now.usec=> 815414
på Windows implementeras inte ett inbyggt systemanrop och därmed finns JVM millisekund precision fallback.Tänk på detta när du räknar med usec
precision i din kod.
> Time.now.usec=> 582000
Trådprioritet
OBS: från åtminstone så tidigt som JRuby 1.7.6 mappas Ruby-trådprioriteringar till Java-trådprioriteringar, så det här avsnittet är inte korrekt-Du kan använda samma prioritet för MR och JRuby.
I MR kan Trådprioriteten ställas in på valfritt värde i Fixnum (om inbyggda trådar är aktiverade) eller -3..3 (Om inte). Standardvärdet är 0.
i JRuby stöds trådar av Java-trådar och prioriteten varierar från 1 till 10, med en standard på 5. Om du skickar ett värde utanför detta intervall till Thread#priority=
, kommer prioriteten att ställas in på 1 eller 10.
OBS: att JVM kan ignorera prioriteringar, det beror verkligen på målet OS och med (äldre) Java måste du skicka extra -XX:UseThreadPriorities
för att de ska användas.
SystemStackError
JRuby kan inte rädda från SystemStackError
. Om din kod är beroende av detta bör du hellre försöka fånga en Java::JavaLang::StackOverflowError
. Se denna biljett för mer information.
Argumentless ’proc’
om du levererar proc
utan argument och metoden råkar ha passerat ett block kommer Ruby att sluta fånga det passerade i blocket. Vissa människor upptäcker detta och det leder till ett sällsynt mönster av proc.call
. Vi stöder inte detta beteende. Problemet är proc som en funktion är relativt vanligt men det tvingar oss att deoptimera alla användningar av proc som proc { #some code }
. Det rekommenderade arbetet är att deklarera blocket uttryckligen med en ampersand def foo(&my_proc)...
. Om du vill att analogt beteende ska proc tillåter vi också Proc.new
som fungerar exakt samma som ett rent proc-samtal.